Php 为什么这个正则表达式匹配得太多?(不会在斜线处停止)
此代码输出Php 为什么这个正则表达式匹配得太多?(不会在斜线处停止),php,regex,Php,Regex,此代码输出$captured数组,但$captured[1]包含条/此而不是我预期的条。我的正则表达式中缺少什么可以阻止返回超过bar <?php $pattern = '/foo/:any/'; $subject = '/foo/bar/this/that'; $pattern = str_replace(':any', '(.+)', $pattern); $pattern = str_replace(':num', '([0-9]+)', $pat
$captured
数组,但$captured[1]
包含条/此
而不是我预期的条
。我的正则表达式中缺少什么可以阻止返回超过bar
<?php
$pattern = '/foo/:any/';
$subject = '/foo/bar/this/that';
$pattern = str_replace(':any', '(.+)', $pattern);
$pattern = str_replace(':num', '([0-9]+)', $pattern);
$pattern = str_replace(':alpha', '([A-Za-z]+)', $pattern);
echo '<pre>';
$pattern = '#^' . $pattern . '#';
preg_match($pattern, $subject, $captured);
print_r($captured);
echo '</pre>';
使用a使+
匹配尽可能少的字符,而不是尽可能多的字符:
$pattern = '#^/foo/:any/#';
您可能还希望将正则表达式四舍五入并将其锚定到字符串的开头:
$pattern = str_replace(':any', '(.+?)', $pattern);
使用a使+
匹配尽可能少的字符,而不是尽可能多的字符:
$pattern = '#^/foo/:any/#';
您可能还希望将正则表达式四舍五入并将其锚定到字符串的开头:
$pattern = str_replace(':any', '(.+?)', $pattern);
圆点是贪婪的,并且匹配尽可能多的字符。要么让它懒惰:
$pattern = str_replace(':any', '([^\/]+)', $pattern);
或者避免与斜杠匹配:
$pattern = '/foo/:any/';
#should be
$pattern = '/foo\/:any/';
圆点是贪婪的,并且匹配尽可能多的字符。要么让它懒惰:
$pattern = str_replace(':any', '([^\/]+)', $pattern);
或者避免与斜杠匹配:
$pattern = '/foo/:any/';
#should be
$pattern = '/foo\/:any/';
您的代码相当混乱和误导,如果运行它,它会输出警告:
警告:preg_match():第1行php shell代码中的未知修饰符“(”
我认为不对的是:
(
[0] => foo/bar/this/that
[1] => bar/this/that
)
因为您需要在regexp中转义正斜杠
修复后,脚本返回:
$pattern = '/foo/(.*?)/' #non greedy
$pattern = '/foo/([^\/]*)/' #not matching any forward slash
$pattern = '@foo/:any/@' #or using different start and end markers, e.g. @
这是一个预期结果。当您使用(.*)
匹配foo/
以及之后的所有内容时。如果要在下一个正斜杠之前匹配任何内容,您有一些可能性:
您的代码相当混乱和误导,如果运行它,它会输出警告:
警告:preg_match():第1行php shell代码中的未知修饰符“(”
我认为不对的是:
(
[0] => foo/bar/this/that
[1] => bar/this/that
)
因为您需要在regexp中转义正斜杠
修复后,脚本返回:
$pattern = '/foo/(.*?)/' #non greedy
$pattern = '/foo/([^\/]*)/' #not matching any forward slash
$pattern = '@foo/:any/@' #or using different start and end markers, e.g. @
这是一个预期结果。当您使用(.*)
匹配foo/
以及之后的所有内容时。如果要在下一个正斜杠之前匹配任何内容,您有一些可能性:
这不是和替换(':any','(.*),$pattern)一样吗?
@walkereno:No。星号仍然是贪婪的(但它允许零次重复,而+
至少需要一次)@walkereno no.+
是一个贪婪的搜索,将获取所有找到的字符,直到找到最后一个/
为止。?
使搜索不贪婪,并在第一次出现/
@Mark时停止:他没有在$captured[1]中获得条/this/that
,这不是很奇怪吗
?@BrianGraham:但是他的模式中的斜杠被当作分隔符。实际上,现在我正在查看它,他应该得到一个“无效模式修饰符”错误,因为foo
将是他的模式,(.+)/
将被解释为模式修饰符…啊,现在他对他的问题进行了评论,解释了他在问题中遗漏了什么…这难道不是和$pattern=str_replace(':any','(.*),$pattern);
@walkereno:不。星号仍然是贪婪的(但它允许零次重复,而+
至少需要一次重复)@walkereno no.+
是一个贪婪的搜索,将获取所有找到的字符,直到找到最后一个/
为止。?
使搜索不贪婪,并在第一次出现/
@Mark时停止:他没有在$captured[1]中获得条/this/that
,这不是很奇怪吗
?@BrianGraham:但是他的模式中的斜杠被当作分隔符。实际上,现在我正在查看它,他应该得到一个“无效模式修饰符”错误,因为foo
将是他的模式,(.+)/
将被解释为模式修饰符…啊,现在他对他的问题进行了评论,解释了他在问题中遗漏了什么…我根本看不出你的正则表达式模式是如何工作的。字符串替换将把它变成/foo/(.+)/
,现在您的模式中有了一个/
模式定界符,但没有转义。在mininum中,它应该看起来像/foo\/(.+)/
使其成为有效的正则表达式。啊,很抱歉,我还有$pattern=''.^'.$pattern.'.'.'.'.'.'
在其中,忘了添加它。我根本看不到您的正则表达式模式如何工作。字符串替换将把它变成/foo/(.+)/
,现在您的模式中有了一个/
模式定界符,但没有转义。在mininum中,它应该看起来像/foo\/(.+)/
使其成为有效的正则表达式。啊,很抱歉,我还有$pattern='#^.$pattern.##
在其中,忘记添加它。我有不同的分隔符,我忘了在原始文章中包含(现在已编辑)像这样:$pattern='.#^.$pattern.#.
,这样我就不必转义前斜杠。我有不同的分隔符,我忘了在原始文章(现在编辑)中包括:$pattern='.#^.$pattern.#
,这样我就不必转义前斜杠了。