在 WordPress 主题中,我使用“posts_where”过滤器将搜索添加到“摘录”字段。当搜索字符串中存在单引号时,它会正常工作,从而导致 SQL 语法错误。
这似乎是 posts_where 过滤器之外的 preg_replace 函数中的一个错误。
例如,对于字符串“o'kine”,posts_where 过滤器中收到的 $where 字符串为:
"AND (((cn_posts.post_title LIKE '%o\'kine%') OR (cn_posts.post_content LIKE '%o\'kine%')))"
然后这是我的 preg_replace 添加 post_excerpt 字段:
$where = preg_replace(
"/post_title\s+LIKE\s*(\'[^\']+\')/",
"post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
以及 $where 之后的值:
"AND (((cn_posts.post_title LIKE '%o\') OR (post_excerpt LIKE '%o\'kine%') OR (cn_posts.post_content LIKE '%o\'kine%')))"
查看导致 SQL 语法错误的“%o\”部分。
预期结果是:
"AND (((cn_posts.post_title LIKE '%o\'kine%') OR (post_excerpt LIKE '%o\'kine%') OR (cn_posts.post_content LIKE '%o\'kine%')))"
这个错误显然存在于我的正则表达式中,更准确地说是存在于我的捕获括号中。我不知道如何处理搜索字符串中零个或多个单引号的可能性?
编辑:根据卡西米尔和希波利特的答案,这是搜索字符串中带有单引号的工作过滤器:
function cn_search_where( $where ) {
$where = preg_replace(
"/post_title\s+LIKE\s*('[^'\\\\]*+(?s:\\\\.[^'\\\\]*)*+')/",
"post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
return $where;
}
最佳答案
将带引号的字符串与最终转义的引号(或其他字符)相匹配的子模式是:
'[^'\\]*+(?s:\\.[^'\\]*)*+'
(请注意,要在正则表达式模式中计算文字反斜杠,必须将其转义,因为反斜杠是特殊字符)
所以在 php 字符串中(反斜杠需要再转义一次):
$pattern = "~'[^'\\\\]*+(?s:\\\\.[^'\\\\]*)*+'~";
有了这些信息,我认为您可以自己构建该模式。
详情:
' # a literal single quote
[^'\\]*+ # zero or more characters that are not a single quote or a backslash
(?s: # open a non-capture group with the s modifier (the dot can match newlines)
\\. # an escaped character
[^'\\]*
)*+ # repeat the group zero or more times
'
关于mysql - 预替换 : capturing single quote inside single quote escaped expression,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33045916/