我想在字符串上使用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条件。)
答案 0 :(得分:3)
你的正则表达式是以消耗大量回溯的方式构建的:
echo preg_ last_ error()
收益2
(PREG_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>';