mysql - 预替换 : capturing single quote inside single quote escaped expression

标签 mysql sql regex wordpress preg-replace

在 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/

相关文章:

mysql - 通过私有(private) IP 拒绝 Google Cloud MySQL 访问,但允许通过公共(public) IP 访问

正则表达式只允许数字、连字符、空格、括号,并应以数字结尾(javascript)

regex - 正则表达式问题

javascript - 正则表达式选择两个字符串之间的所有内容,但不选择其中一个字符串

mysql - 从表中获取一组输入的下一个最大时间

mysql - rake db:migrate 失败并出现 Mysql2::Error: Row size Too Large

mysql - 1064 您的 SQL 语法有误; - 显示在我的网站

java - 这是转义 SQL 查询参数的安全方法吗?

sql - 如何从Firebird中的非表中选择数据?

mysql - 如何在 MySQL 中将默认 Null 更改为 NOT NULL