Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression lookbehind problem

I use

(?<!value=\")##(.*)##

to match string like ##MyString## that's not in the form of:

<input type="text" value="##MyString##">

This works for the above form, but not for this: (It still matches, should not match)

<input type="text" value="Here is my ##MyString## coming..">

I tried:

(?<!value=\").*##(.*)##

with no luck. Any suggestions will be deeply appreciated.

Edit: I am using PHP preg_match() function

like image 440
Ali Selcuk Avatar asked Feb 05 '10 23:02

Ali Selcuk


People also ask

Can I use regex Lookbehind?

The good news is that you can use lookbehind anywhere in the regex, not only at the start.

How do you use negative Lookbehind regex?

Negative Lookbehind Syntax:Where match is the item to match and element is the character, characters or group in regex which must not precede the match, to declare it a successful match. So if you want to avoid matching a token if a certain token precedes it you may use negative lookbehind. For example / (? <!

Does sed support Lookbehind?

sed does not support lookaround assertions. For what it's worth, grep -P is also a nonstandard extension, though typically available on Linux (but not other platforms).

Does grep support Lookbehind?

Apart from looking ahead, you can also look back (or "behind," as it's called in the world of GREP). The general format for positive lookbehind is (? <=) .


2 Answers

This is not perfect (that's what HTML parsers are for), but it will work for the vast majority of HTML files:

(^|>)[^<>]*##[^#]*##[^<>]*(<|$)

The idea is simple. You're looking for a string that is outside of tags. To be outside of tags, the closest preceding angled bracket to it must be closing (or there's no bracket at all), and the closest following one must be opening (or none). This assumes that angled brackets are not used in attribute values.

If you actually care that the attribute name be "value", then you can match for:

value\s*=\s*"([^\"]|\\\")*##[^#]*##([^\"]|\\\")*\"

... and then simply negate the match (!preg_match(...)).

like image 142
Max Shawabkeh Avatar answered Sep 23 '22 22:09

Max Shawabkeh


@OP, you can do it simply without regex.

$text = '<input type="text" value="   ##MyString##">';
$text = str_replace(" ","",$text);
if (strpos($text,'value="##' ) !==FALSE ){
    $s = explode('value="##',$text);
    $t = explode("##",$s[1]);
    print "$t[0]\n";
}
like image 1
ghostdog74 Avatar answered Sep 22 '22 22:09

ghostdog74