docdawson:
this side might be interesting for you: php-regex
Thank you for your reply, Doc! Whoa!
Is it that obvious that I'm from Germany? Or are you?
Actually, I know this site quite well and have been able to do quite a lot of "simple" regexps for a while. But this problem has me stumped.
Seems like I have not been precise enough describing my problem. I will try to be now with a more hands-on example:
I have a map of column names to replace in the user supplied SQL where clause like:
| search | replace |
| user |
username |
| password |
pass |
| wronglogins |
login_fail_counter |
My input string might be something like (the "WHERE" has not necessarily to be part of it):
"user='foo user bar' AND password = 'sec''ret' AND wronglogins <= 3"
Note that spaces next to operators like = are not guaranteed, there might be spaces ('foo user bar') as well as SQL escaped quotes ('sec''ret') in quoted text, "AND" might be another operator, etc. Actually any valid SQL where clause might be possible.
The output of my mystery regexp function should be:
"username='foo user bar' AND pass = 'sec''ret' AND login_fail_counter <= 3"
Note that "user" in the quoted 'foo user bar' has not been changed. Every occurence of the search string NOT within quotes has been replaced.
My idea was to walk through the map like this (I might be able to do this in one step using preg_replace with patterns and replace-arrays):
$input = "user='foo user bar' AND password = 'sec''ret' AND wronglogins <= 3";
foreach ($map as $search => $replace) {
$input = preg_replace("/mystery pattern with $search in it somewhere/", $replace, $input);
}
echo $input;
Output should be the above string:
"username='foo user bar' AND pass = 'sec''ret' and login_fail_counter <= 3"
Ideally $search should be surrounded by some kind of word boundaries, so that "password" does not match "other_password='foobar'".
Right now I'm using a really really dirty hack that matches quoted strings or $search, replacing (using a callback) with $replace if the match is not a quoted string, otherwise with "\\0". I am evading the fixed length look behind problem this way. I might be totally on the wrong track with this though.