Page 1 of 1

Case-insensitive, lookaround, variable replacement!

Posted: Tue Feb 07, 2006 9:49 pm
by CobraCards
I need to look take a long text string and replace certain smaller strings within it. Specific requirements:

1) The strings to match need to be passed as variables.

2) Matches should look ahead (and behind) to non-alphabetical characters. (The point being to prevent matches within a word -- e.g., I don't want "sting" to match "interesting.")

3) I need this to be case-INsensitive.


I've discovered ways of doing each of these things individually, but for some reason I can't get them to work together. For example, I can only manage to get case-insensitive results with eregi_replace, but I can only get the lookaround to work with preg_replace.

How can I do all these things at once? :)

Posted: Tue Feb 07, 2006 9:51 pm
by feyd
so what's the question?

fyi, preg_replace can do case-insensitive: i modifer.

Posted: Tue Feb 07, 2006 10:20 pm
by feyd
we're going to need more information. Like excerpts of the text, both the text you're trying to find and example strings to best understand.

Posted: Tue Feb 07, 2006 10:55 pm
by CobraCards
To give the background, this code will be used to search messages posted to my trading card game forums, and turn all card titles (a few thousand possibilities, the full list is pulled from a database) into links to that card's image and text.

In the code I'm currently using, the line that does the replacement looks something like this:

Code: Select all

$message = str_replace($match, $link, $message)
$match is an array containing all the cardnames in order, and $link is an array containing the same card names, surrounded by the code that makes them links.

This works OK, but could be better. For example, take the following pair of sentences -- the matches I want are bolded.
"i prefer using sting in this deck, as it has shown some great results in playtesting"
"Sting rules!"

The current code would find only one match as follows. (To correct this, I'd need to make it case-insensitive.)
"i prefer using sting in this deck, as it has shown some great results in playtesting"
"Sting rules!"

But, once I do that, I get too many matches:
"i prefer using sting in this deck, as it has shown some great results in playtesting"
"Sting rules!"

So now, I need to prevent it from matching partial words. (Checking the characters before and after the match seemed the logical way to do this, please let me know if there's a better approach!)

Just to clarify, I know how to put together a regex that would match "Sting" as described above, but when I replace that word with the variable $match (remember that "Sting" is one of a few thousand card titles that need to be checked!) I can't make it work.

Posted: Tue Feb 07, 2006 11:23 pm
by feyd

Code: Select all

function quoted($a) {
  return preg_quote($a,'#');
}
$match = implode('|',array_map('quoted',array_map('trim',$match)));
$string = preg_replace('#(?<![a-z0-9])('.$match.')(?![a-z0-9])#','<b>\\1</b>',$string);
try that.

Posted: Wed Feb 08, 2006 1:35 pm
by CobraCards
Cool, thanks... I wasn't able to plug that in directly, but looking at your regex led me to the answer I needed. :)

I ran into one more hurdle, will start a new thread for it though.

Posted: Wed Feb 08, 2006 2:44 pm
by raghavan20
why this kind of simple thing would not work?

Code: Select all

$regex = "#\b".$match[someIndex]."\b#i"; // $match[someIndex] should be your match word like sting...
I am actually unable to understand when you say matching bold strings... :roll: