繁体   English   中英

用于匹配单引号字符串的正则表达式在 PHP 中失败

[英]Regex for matching single-quoted strings fails with PHP

所以我有这个正则表达式:

/'((?:[^\\']|\\.)*)'/

它应该匹配单引号字符串,同时忽略内部转义单引号\\'

在这里工作,但是当用 PHP 执行时,我得到不同的结果。 这是为什么?

使用负向后视可能更容易。 另请注意,您需要对斜杠进行两次转义——一次是告诉 PHP 您想要一个文字反斜杠,然后再次告诉正则表达式引擎您想要一个文字反斜杠。

另请注意,您的捕获表达式 ( .* ) 是贪婪的 - 它会捕获'字符之间'所有内容,包括其他'字符,无论它们是否被转义。 如果您希望它在第一个未转义的'之后停止,请使用.*? 反而。 我在下面的示例中使用了非贪婪版本。

<?php

$test = "This is a 'test \' string' for regex selection";
$pattern = "/(?<!\\\\)'(.*?)(?<!\\\\)'/";

echo "Test data: $test\n";
echo "Pattern:   $pattern\n";

if (preg_match($pattern, $test, $matches)) {
    echo "Matches:\n";
    var_dump($matches);
}

这有点逃离地狱。 尽管已经有一个公认的答案,但原始模式实际上更好。 为什么? 它允许使用 Jeffery Friedl 在“掌握正则表达式”中描述的展开循环技术来转义转义字符: "([^\\\\"]*(?:\\\\.[^\\\\"]*)*)" (适用于单引号)

演示

展开循环(使用双引号)

"                              # the start delimiter
 ([^\\"]*                      # anything but the end of the string or the escape char
         (?:\\.                #     the escape char preceding an escaped char (any char)
               [^\\"]*         #     anything but the end of the string or the escape char
                      )*)      #     repeat
                             " # the end delimiter

这并不能解决逃离地狱的问题,但您也已在此处进行了介绍:

示例代码

$re = '/\'([^\\\\\']*(?:\\\\.[^\\\\\']*)*)\'/';
$str = '\'foo\', \'can\\\'t\', \'bar\'
\'foo\', \' \\\'cannott\\\'\\\\\', \'bar\'
';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM