preg_replace:在单引号转义表达式中捕获单引号

时间:2015-10-09 19:38:26

标签: mysql sql regex wordpress preg-replace

在wordpress主题中,我正在使用" posts_where"过滤以将搜索添加到"摘录"领域。当搜索字符串中有单引号时,它正常工作,导致SQL synthax错误。

这似乎是关于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 );

以及$之后的值:

"AND (((cn_posts.post_title LIKE '%o\') OR (post_excerpt LIKE '%o\'kine%') OR (cn_posts.post_content LIKE '%o\'kine%')))"

请参阅'%o \'导致SQL synthax错误的部分。

预期结果将是:

"AND (((cn_posts.post_title LIKE '%o\'kine%') OR (post_excerpt LIKE '%o\'kine%') OR (cn_posts.post_content LIKE '%o\'kine%')))"

这个错误显然在我的正则表达式中,更准确地说是在我的捕获括号中。我不知道如何处理搜索字符串中零或多个单引号的可能性?

编辑:Casimir et Hippolyte回答说,这是搜索字符串中带有单引号的工作过滤器:

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;
} 

1 个答案:

答案 0 :(得分:0)

将带引号的字符串与最终转义引号(或其他字符)匹配的子模式为:

'[^'\\]*+(?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
'