Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个正则表达式在PHP中不贪婪_Php_Regex_Preg Replace Callback - Fatal编程技术网

为什么这个正则表达式在PHP中不贪婪

为什么这个正则表达式在PHP中不贪婪,php,regex,preg-replace-callback,Php,Regex,Preg Replace Callback,此正则表达式应与Markdown中的列表一样匹配: /((?:(?:(?:^[\+\*\-] )(?:[^\r\n]+))(?:\r|\n?))+)/m 它可以在Javascript中工作(添加了g标志),但是我在将它移植到PHP时遇到了问题。它的行为并不贪婪。下面是我的示例代码: $string = preg_replace_callback('`((?:(?:(?:^\* )(?:[^\r\n]+))(?:\r|\n?))+)`m', array(&$this, 'bullet_l

此正则表达式应与Markdown中的列表一样匹配:

/((?:(?:(?:^[\+\*\-] )(?:[^\r\n]+))(?:\r|\n?))+)/m
它可以在Javascript中工作(添加了
g
标志),但是我在将它移植到PHP时遇到了问题。它的行为并不贪婪。下面是我的示例代码:

$string = preg_replace_callback('`((?:(?:(?:^\* )(?:[^\r\n]+))(?:\r|\n?))+)`m', array(&$this, 'bullet_list'), $string);

function bullet_list($matches) { var_dump($matches) }
当我向其馈送一个包含三行的列表时,它会显示以下内容:

array(2) { [0]=> string(6) "* one " [1]=> string(6) "* one " } array(2) { [0]=> string(6) "* two " [1]=> string(6) "* two " } array(2) { [0]=> string(8) "* three " [1]=> string(8) "* three " } 
显然,
var_dump
被调用了三次,而不是像我期望的那样只调用一次,因为正则表达式是贪婪的,必须匹配尽可能多的行。我已经在regex101.com上测试过了。
如何使其正常工作?

如果输入文本中有
\r\n
换行符,则此正则表达式将无法正常工作

零件
(?:\r\n?
\r
\n
匹配,但不能两者都匹配。(regex101只将换行符视为
\n
,因此它在那里工作)

下面的方法有效吗

/(?:(?:(?:^[+*-] )(?:[^\r\n]+))[\r\n]*)+/m
(或者,在删除所有不必要的非捕获组后-谢谢@M42!)


如果输入文本中有
\r\n
换行符,此正则表达式将无法正常工作

零件
(?:\r\n?
\r
\n
匹配,但不能两者都匹配。(regex101只将换行符视为
\n
,因此它在那里工作)

下面的方法有效吗

/(?:(?:(?:^[+*-] )(?:[^\r\n]+))[\r\n]*)+/m
(或者,在删除所有不必要的非捕获组后-谢谢@M42!)


您的正则表达式可以减少为:

(?:^[+*-] [^\r\n]+\R*)+
不需要进行所有这些分组。
\R
表示任何类型的换行
\n
\R
\R\n

编辑:
\R
在字符类中失去其特殊含义<代码>[\R]表示
R


多亏了HamZa,您的正则表达式可以减少到:

(?:^[+*-] [^\r\n]+\R*)+
不需要进行所有这些分组。
\R
表示任何类型的换行
\n
\R
\R\n

编辑:
\R
在字符类中失去其特殊含义<代码>[\R]表示
R


多亏了HamZa

这将匹配所有带项目符号的行,直到到达未带项目符号的第一行

(?<=^|\R)\*[\s\S]+?(?=$|\R[^*])

(?这将匹配所有带项目符号的行,直到它到达未带项目符号的第一行

(?<=^|\R)\*[\s\S]+?(?=$|\R[^*])


(?那些backticks真的存在吗?@TimPietzcker backticks作为regexmodifiers@TimPietzcker修正了。当我不需要toAh时,我用反斜杠来逃避反斜杠,我把反斜杠看作斜杠,然后感到困惑:)你需要小心,因为你的匹配只在文本以项目符号列表开头时有效。它也只匹配一个列表。如果你想匹配所有列表,请参阅我的答案。那些倒勾真的存在吗?@TimPietzcker backticks as regexmodifiers@TimPietzcker修正了。当我不需要时用反斜杠来逃避反斜杠,我已经看到了反斜杠s为斜杠,并且感到困惑:)您需要小心,因为只有当文本以项目符号列表开头时,您的匹配才有效。它也只匹配一个列表。如果要匹配所有列表,请查看我的答案。我不知道
\R
快捷方式,很好!这不也会匹配后续的非列表行吗?@TimPietzcker:是的,它对缩短正则表达式非常有用。请参见@M42上的§Backslash-R选项不幸的是,
\R
在字符类中不起作用<代码>[\R]
@HamZa:是的,你说得对。太糟糕了。。。答案被相应地编辑了。我不知道
\R
快捷方式,很好!这不也会匹配后续的非列表行吗?@TimPietzcker:是的,它对缩短正则表达式非常有用。请参见@M42上的§Backslash-R选项不幸的是,
\R
在字符类中不起作用<代码>[\R]
@HamZa:是的,你说得对。太糟糕了。。。答案经过相应编辑。是的,它可以工作,但您忘记将整个表达式括在括号中:
/(?:(?:(?:(?:(?:^[+*-])(?:[^\r\n]+)[\r\n]*)+)/m
@Juribiyan:不需要外部参数是的,它可以工作,但您忘记将整个表达式括在括号中:
/(?:(?:(?:(?:(?:(?:(?:^-[+*])(?:(?:^-])(?:(?:^-])(?:(?:^-])(?:(?:[+++))+)(?:)(?:)(?:))(?:(/m
@Juribiyan:character类中的
\R
不需要外部参数。@非常感谢HamZa,这总是让我感到困惑。需要记住这是一场位置赛。关于字符类中的
\R
。@HamZa非常感谢,这总是让我感到困惑。需要记住这是一场位置赛。