Forum Moderators: coopster

Message Too Old, No Replies

preg question time

match a string that does not contains a substring

         

Xuefer

8:42 am on Sep 14, 2003 (gmt 0)

10+ Year Member



example:
use preg_match_all to match
"a's'd'fas'df'abc'df"
i want to get => 's', 'fas'
but don't get 'abc'

in another word: match a string that start with "'" end with "'", which does not contains abc

how to do it?

jatar_k

11:55 pm on Sep 15, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



c'mon regex folk, I know you know this ;)

coopster

10:54 pm on Sep 16, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Well, I'm not sure if this is going to work for you and I'm sure there are better REGEX authors out there than myself, but here is what I can come up with:

$string = "a's'd'fas'df'abc'df'_'abc''xyz'abcd'llc";
if (preg_match_all("/('abc')¦('.*?')/", $string, $matches)) {
foreach ($matches[2] as $char) {if ($char) print $char . '<br />';}
}

produces the following output:

's'
'fas'
'_'
''
'abcd'

You know, somebody on the Perl board may be able to come up with a better solution. I'll post a message linking to this board to see if there are any takers over there.

Xuefer

2:40 am on Sep 17, 2003 (gmt 0)

10+ Year Member



thanks
it should work

after studying your pattern i get:
preg_replace_callback("/(?:'abc'¦('.*?'))/", 'callback', $string);
may work? going to test..

but i still don't know how to mate a string that doesn't contains specified substring
[^abcdefg] is match only 1 char that isn't one of "abcdefg"
but not for a 'sequence of chars'(string)

Asandir

8:41 pm on Sep 17, 2003 (gmt 0)

10+ Year Member



>but i still don't know how to mate a string that doesn't contains specified
>substring [^abcdefg] is match only 1 char that isn't one of "abcdefg"
>but not for a 'sequence of chars'(string)

Add a modifier after the chars. Eg, to match at least one char or more, [a-zA-Z]+
To match many or none chars that are not alphabetical, [^a-zA-Z]*

bcolflesh

8:45 pm on Sep 17, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



[^abcdefg] is match only 1 char that isn't one of "abcdefg" but not for a 'sequence of chars'(string)

[^abcdefg^] excludes the string inside the carets - is that what you need?

coopster

9:19 pm on Sep 17, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



[^abcdefg^] excludes the string inside the carets
bcolflesh, are you sure about that? My understanding is that the caret (^) negates the character class, but only if it is the first character. Negating the character class means if any of the individual characters are found, not the exact string. I tested the regex you showed here and did not receive the results expected. Please confirm. Thanks, Coopster.

bcolflesh

9:29 pm on Sep 17, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Against the string mentioned at the beginning, try:

preg_match_all ("'[^abc^].'", $your_string, $result_string);

coopster

10:17 pm on Sep 17, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Try for yourself:

$string = "a's'd'fas'df'abc'df";
if (preg_match_all("/'[^abc^].'/", $string, $matches)) {
print "<pre>"; print_r($matches); print "</pre>";
}

returns:

Array
(
[0] => Array
(
[0] => 'df'
)

)

Xuefer

1:35 am on Sep 18, 2003 (gmt 0)

10+ Year Member



i know [abc] and [^abc], and i need to exclude (abc), not [abc]
and what's [^abc^]? seems no different from [^abc], except it has one more char

MonkeeSage

2:08 am on Sep 18, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What about reversing your logic here, Xuefer?

I'm almost positive that /((abc)+)/ will match at least one occurance of the string "abc", so instead of only getting lines that don't have "abc", only gets lines if the match is empty.

Id est, if you match the substring, replace it with "" or ignore the string totally, but if you don't match it, then use the string.

Would that be an option? Just thinking out loud....

Jordan

coopster

2:30 am on Sep 18, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



[edit] response to post number 10, MonkeeSage slipped in before me [/edit]
That's exactly what bcolflesh and I have been discussing. If you are trying to match a certain string, simply key the string, don't put it in a character class (meaning: surrounded by brackets [] ). If you notice in post #3, 'abc' is not in a character class and the string is found. However, I've used an alternative branch, the pipe (¦), to fill up a second subpattern array with those that are not 'abc' strings. Since we are searching for words wrapped withing single quotes, I don't believe we need to use word boundaries (\b).

bcolflesh

2:40 am on Sep 18, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Doh! - Coopster is correct - I should test first - ignore my previous reply - if I alter coopster's code slightly:

$string = "a's'd'fas'df'abc'df";
if (preg_match_all("/'[^a^b^c].*?'/", $string, $matches)) {
print "<pre>"; print_r($matches); print "</pre>";
}

I get the results you originally asked for:

Array
(
[0] => Array
(
[0] => 's'
[1] => 'fas'
)

)

MonkeeSage

2:42 am on Sep 18, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ah-ha, forgive my redundancy. I only skimmed through the thread. My bad!

Jordan

Xuefer

3:16 am on Sep 18, 2003 (gmt 0)

10+ Year Member



to msg #13
your code is exactly the same as
<?php
$string = "a's'd'fas'df'abc'df";
if (preg_match_all("/'[^abc^].*?'/", $string, $matches)) {
print "<pre>"; print_r($matches); print "</pre>";
}
?>
"[^abc^].*" or "[^a^b^c].*"
only test the first char immediately after "'"

so: $string = "'eabc'a's'd'fas'df'abc'df";
match result is:
Array
(
[0] => Array
(
[0] => 'eabc'
[1] => 's'
[2] => 'fas'
)

)

"'eabc'" contains "abc"

maybe coopster is right: match it, and throw it