Page 1 of 1

help with regular expressions: Warning: Unknown modifier

Posted: Mon Jul 17, 2006 1:36 pm
by fgomez
Hello,

The website I'm working on has a search function which displays the results with matches for the search term in bold. This effect is achieved with a simple snippet:

Code: Select all

$description = str_replace($q, "<strong>$q</strong>", $description);
The problem is that sometimes the search term is part of a URL in an <a> tag, which makes for the following undesirable output:

Code: Select all

<a href="http://www.<strong>searchterm</strong>.com/">some hyperlinked text</a>
After adding a little code to rectify this (to follow), I get the following PHP warning:
Warning: Unknown modifier ']' in /food/bar/search3.php on line 41
Here are lines 40 and 41 of the new code:

Code: Select all

$needle = "<a[^>]*>.*(".preg_quote($q)."|".preg_quote($q_uc).").*</a>" ;
if(!preg_match($needle, $description)) { /*some stuff*/ }
The idea was to highlight the search term only for records where the search term does not appear between <a> and </a>. This was supposed to be a quick fix; ideally, I'd like to be able to turn off the highlighting just for matches within the tags.

For example, I'd like the following to work:

Code: Select all

I like <strong>coffee</strong>.  Visit <a href="http://www.coffee.com/">www.<strong>coffee</strong>.com</a>.
The way I've written it (which doesn't even work), there would be no bolding at all.

Can anyone help with this? I especially need help with the unknown modifier warning; I might be able to figure out the rest on my own, though some help there would be appreciated as well. :wink:

Thanks,

Posted: Mon Jul 17, 2006 1:40 pm
by Burrito
you need to add a delimiter in your pattern:

ex: untested

Code: Select all

$needle = "/<a[^>]*>.*(".preg_quote($q)."|".preg_quote($q_uc).").*</a>/" ;

Posted: Mon Jul 17, 2006 1:53 pm
by fgomez
I've never heard of a delimiters in this context before. Haven't tried the code yet, will let you know when I do. In the meantime, can you point me to some documentation on delimiters? Sounds like something I need to know!

Posted: Mon Jul 17, 2006 1:56 pm
by Burrito
here is the best regex tutorial in the entire world...it explains all about them:

viewtopic.php?t=33147

Posted: Mon Jul 17, 2006 3:33 pm
by fgomez
Checked out the tutorial, added the delimiters, still no luck. The warning has changed though. Now it says:
Warning: Unknown modifier 'a' in /food/bar/search3.php on line 41
whereas before it said
Warning: Unknown modifier ']' in /food/bar/search3.php on line 41
Arg... I've spent waaay too much time on this. Help?!?!?

Posted: Mon Jul 17, 2006 3:38 pm
by Weirdan
you need to escape the delimiter in the "</a>" part with backslash:

Code: Select all

$needle = "/<a[^>]*>.*(" . preg_quote($q, "/") . "|" . preg_quote($q_uc, "/") . ").*<\/a>/" ;

Posted: Mon Jul 17, 2006 3:57 pm
by fgomez
Thank you. The warning is gone.

Usually I use ereg instead of preg_match. Does ereg not require the delimiters? I've never used them before and never experienced problems.

Hmm... the script is still not behaving the way I think it should. I probably need to look at the regex again. I guess I'll rebuild it bit by bit. It's not nonsensical though, is it?

Thanks for all your help.

Posted: Mon Jul 17, 2006 4:04 pm
by Weirdan
Usually I use ereg instead of preg_match. Does ereg not require the delimiters? I've never used them before and never experienced problems.
Posix regexps (ereg* family) do not require delimiters. Perl regexps (preg_*) do.
Hmm... the script is still not behaving the way I think it should.
what is $q_uc ? $q in upper case?

Posted: Mon Jul 17, 2006 4:07 pm
by fgomez

Code: Select all

$q_uc = ucwords($q);

Posted: Mon Jul 17, 2006 4:11 pm
by Weirdan
I guess for search term highlighting you'd better use case insensitive regexp:

Code: Select all

$needle = "/<a[^>]*>.*?" . preg_quote($q, "/") . ".*?<\/a>/i" ;
Also I would make .* parts non-greedy (add ? to them).

Posted: Mon Jul 17, 2006 4:39 pm
by fgomez
Nope, same misbehavior. In any case, to prevent the app from breaking, I've done this in the meantime:

Code: Select all

$needle = "/<a/" ;
This turns off highlighting for any record with an <a> tag in the description. I'm willing to live with this until I have a little more time to look into it. I'll post a more elegant solution when I get around to working on it.

Thanks, everyone, for your help. The delimiters thing was not covered in any other regex tutorials I read before (which were not geared towards PHP), and I wouldn't have figured that out on my own this quickly.