preg_replace返回空字符串(不匹配)

时间:2013-04-24 18:30:45

标签: php regex preg-replace

我想在字符串上使用preg_replace,但是虽然字符串不匹配,但我得到一个空字符串作为返回字符串。

PHP Code:
    $sql = "k1 LIKE 'n' OR k2 LIKE 'n' OR k3 LIKE 'n' OR k4 LIKE 'n' OR k5 LIKE 'n' OR k6 LIKE '1' ";
    print "SQL: $sql<br>";
    $sql_A = preg_replace("/^([\w]+ LIKE\s?'?.*?'? OR )+ $/", "##$1##", $sql);
    print "=> $sql_A<br>";

返回:

SQL: k1 LIKE 'n' OR k2 LIKE 'n' OR k3 LIKE 'n' OR k4 LIKE 'n' OR k5 LIKE 'n' OR k6 LIKE '1'
=>

奇怪的是,正则表达式甚至不匹配。 我尝试在获得相同结果时尽可能地简化字符串。我也可以在结束前添加一个OR- $。但是一旦我放下一些或添加......否则,我会得到正常的行为和正确的替代品。

有谁知道为什么会这样?也许我犯了一个错误,我没有看到,也许这是一个错误? 我迷路了...

(在LINUX服务器上使用PHP版本5.3.21)

--- 2013-04-24 21:30 ---

编辑:

如果有帮助,我最初使用的数据是:

$sql = "SELECT count(*) AS anz FROM xxx_table LEFT JOIN yyy_table on yyy_table.devo=xxx_table.devo LEFT JOIN zzz_table ON (yyy_table.status=zzz_table.sid AND lang=1 AND yyy_table.for =zzz_table.for) LEFT JOIN kunde k on k.kd_nr = yyy_table.kd_nr LEFT JOIN locations l on l.lok_nr = yyy_table.lok_nr WHERE xxx_table.clear!='Y' AND xxx_table.ign!='Y' AND name NOT LIKE 'Container:%' AND name LIKE '%' AND event_prio LIKE '%' AND zzz_table.show='Y' AND ( k.ikd_nr LIKE '%n%' OR k.such LIKE '%n%' OR k.adr1 LIKE '%n%' OR k.adr2 LIKE '%n%' OR k.ort LIKE '%n%' OR k.strasse LIKE '%n%' )";
$sql_A = preg_replace("/(\((\s*[\w\.\-\`]+ (LIKE\s|=)\s*'?.+?'?\s*OR)* [\w\.\-\`]+ LIKE '%' (OR [\w\.\-\`]+ (LIKE\s|=)\s*'?.+?'?\s*)*\))/i", "", $sql);

同样,结果是NULL(不是我学过的空字符串;) (清除此preg_replace是为了识别具有LIKE'%'模式的SQL语句中的OR条件,以删除那些不必要的OR条件。)

2 个答案:

答案 0 :(得分:3)

你的正则表达式是以消耗大量回溯的方式构建的:

 echo preg_ last_ error()

收益2PREG_BACKTRACK_LIMIT_ERROR

你当然可以增加回溯:

 ini_set("pcre.backtrack_limit",100000000);

...这会使这个正则表达式不起作用(因为它不匹配),但它至少会返回原始字符串。创建一个更有效的正则表达式看起来更有吸引力,但为了做到这一点,我需要一个理想的输入&amp;输出

修改

再看一下,我认为这个正则表达式可能对你有所帮助:

$sql_A = preg_replace(
   "/(\w+ LIKE\s*('(\\\.|[^'\\\]|)*'|[^\s]+))/",
   "##<$1>##",
   $sql);

答案 1 :(得分:0)

试试这个:

$sql = "k1 LIKE 'n' OR k2 LIKE 'n' OR k3 LIKE 'n' OR k4 LIKE 'n' OR k5 LIKE 'n' OR k6 LIKE '1' ";
$pattern = "~(?>\w++(?>\.\w++)?\h++LIKE\h++'[^']++'\h++OR\h++)*+\w++(?>\.\w++)?\h++LIKE\h++'[^']++'~";
$result = preg_replace($pattern, "##$0##",$sql);
echo '<pre>' . print_r($result, true) . '</pre>';