0

我想在字符串上使用 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'
=>

奇怪的是,正则表达式甚至不匹配。我试图在得到相同结果的同时尽可能地简化字符串。我也可能会在 end-$ 之前添加一个 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 条件。)

4

2 回答 2

3

您的正则表达式的构建方式会消耗大量回溯:

 echo preg_ last_ error()

产量2( PREG_BACKTRACK_LIMIT_ERROR)

你当然可以增加回溯:

 ini_set("pcre.backtrack_limit",100000000);

...这会使这个正则表达式不起作用(因为它不匹配),但它至少会返回原始字符串。创建一个更高效的正则表达式似乎更有吸引力,但要实现这一点,我需要一个所需的输入和输出。

编辑:

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

$sql_A = preg_replace(
   "/(\w+ LIKE\s*('(\\\.|[^'\\\]|)*'|[^\s]+))/",
   "##<$1>##",
   $sql);
于 2013-04-24T18:38:02.733 回答
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>';
于 2013-04-24T21:58:42.090 回答