Welcome to WebmasterWorld Guest from 35.172.195.49

Forum Moderators: coopster & jatar k

Message Too Old, No Replies

preg question time

match a string that does not contains a substring

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

Preferred Member

10+ Year Member

joined:Nov 19, 2002
posts:372
votes: 0


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?

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

Administrator

WebmasterWorld Administrator jatar_k is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 24, 2001
posts:15756
votes: 0


c'mon regex folk, I know you know this ;)
10:54 pm on Sept 16, 2003 (gmt 0)

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12555
votes: 3


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.
2:40 am on Sept 17, 2003 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 19, 2002
posts:372
votes: 0


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)

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

Junior Member

10+ Year Member

joined:Oct 8, 2002
posts:65
votes: 0


>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]*

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

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2003
posts:2355
votes: 0


[^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?

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

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12555
votes: 3


[^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.
9:29 pm on Sept 17, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2003
posts:2355
votes: 0


Against the string mentioned at the beginning, try:

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

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

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12555
votes: 3


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'
)

)

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

Preferred Member

10+ Year Member

joined:Nov 19, 2002
posts:372
votes: 0


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
2:08 am on Sept 18, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:July 26, 2003
posts:881
votes: 0


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

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

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12555
votes: 3


[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).
2:40 am on Sept 18, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2003
posts:2355
votes: 0


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'
)

)

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

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:July 26, 2003
posts:881
votes: 0


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

Jordan

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

Preferred Member

10+ Year Member

joined:Nov 19, 2002
posts:372
votes: 0


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