此代码输出$captured
数组,但$captured[1]
包含bar/this
而非预期的bar
。我的正则表达式中缺少什么来阻止返回超过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>';
答案 0 :(得分:5)
使用non-greedy modifier将+
匹配为少数字符,而不是许多:
$pattern = str_replace(':any', '(.+?)', $pattern);
^
您可能还想在正则表达式中添加delimiters并将其锚定到字符串的开头:
$pattern = '#^/foo/:any/#';
答案 1 :(得分:1)
点贪婪,尽可能多地匹配字符。让它变得懒惰:
$pattern = str_replace(':any', '(.+?)', $pattern);
或防止匹配斜杠:
$pattern = str_replace(':any', '([^\/]+)', $pattern);
答案 2 :(得分:0)
您的代码相当混乱和误导,如果运行它,它会输出一个警告:
警告:preg_match():未知的修饰符&#39;(&#39;在第1行的php shell代码中
我认为错误的是:
$pattern = '/foo/:any/';
#should be
$pattern = '/foo\/:any/';
因为你需要在正则表达式中转义正斜杠。
修复此问题后,脚本将返回:
(
[0] => foo/bar/this/that
[1] => bar/this/that
)
这是预期的结果。当您将foo/
和之后的所有内容与(.*)
匹配时。如果你想匹配任何东西,直到下一个正斜杠你有一些可能性:
$pattern = '/foo/(.*?)/' #non greedy
$pattern = '/foo/([^\/]*)/' #not matching any forward slash
$pattern = '@foo/:any/@' #or using different start and end markers, e.g. @