php > preg_match("@/m(/[^/]+)+/t/?@", "/m/part/other-part/t", $m);
php > var_dump($m);
array(2) {
[0]=>
string(20) "/m/part/other-part/t"
[1]=>
string(11) "/other-part"
}
php > preg_match_all("@/m(/[^/]+)+/t/?@", "/m/part/other-part/t", $m);
php > var_dump($m);
array(2) {
[0]=>
array(1) {
[0]=>
string(20) "/m/part/other-part/t"
}
[1]=>
array(1) {
[0]=>
string(11) "/other-part"
}
}
通过上述示例,我希望捕获与/part
和/other-part
匹配,遗憾的是,正则表达式/m(/[^/]+)+/t/?
并未像我预期的那样捕获这两者。
此捕获不应仅限于匹配此样本,它应捕获捕获组的未定义重复次数;例如/m/part/other-part/and-another/more/t
更新 鉴于这是预期的行为,我的问题就是如何实现我的匹配?
答案 0 :(得分:2)
这就是捕捉群体的方式。重复捕获组只有在正则表达式完成后存储的最后一个匹配。那是你的测试“/ other-part”。
试试这个
/m((?:/[^/]+)+)/t/?
看到它here on Regexr,将鼠标悬停在匹配项上时,您可以看到捕获组的内容。
只需在开始时添加?:
并在整个重复过程中添加另一个,即可使您的群组无法捕获。
在php中
preg_match_all("@/m((?:/[^/]+)+)/t/?@", "/m/part/other-part/t", $m);
var_dump($m);
输出:
array(2) {
[0]=> array(1) {
[0]=>
string(20) "/m/part/other-part/t"
}
[1]=> array(1) {
[0]=>
string(16) "/part/other-part"
}
}
答案 1 :(得分:2)
试试这个:
preg_match_all("@(?:/m)?/([^/]+)(?:/t)?@", "/m/part/other-part/another-part/t", $m);
var_dump($m);
它给出了:
array(2) {
[0]=>
array(3) {
[0]=>
string(7) "/m/part"
[1]=>
string(11) "/other-part"
[2]=>
string(15) "/another-part/t"
}
[1]=>
array(3) {
[0]=>
string(4) "part"
[1]=>
string(10) "other-part"
[2]=>
string(12) "another-part"
}
}
//编辑
IMO做你想做的事情的最好方法是使用 @stema 中的preg_match()并按/
分解结果以获得你想要的部分列表。
答案 2 :(得分:0)
正如评论中已经写过的那样,你不能一次做到这一点,因为preg_match
不允许你返回相同的子组匹配(就像你可以用Javascript或.Net做的那样,见 Get repeated matches with preg_match_all() 的)。因此,您可以将操作分为多个步骤:
代码:
$subject = '/m/part/other-part/t';
$subpattern = '/[^/]+';
$pattern = sprintf('~/m(?<path>(?:%s)+)/t/?~', $subpattern);
$r = preg_match($pattern, $subject, $matches);
if (!$r) return;
$r = preg_match_all("~$subpattern~", $matches['path'], $matches);
var_dump($matches);
输出:
array(1) {
[0]=>
array(2) {
[0]=>
string(5) "/part"
[1]=>
string(11) "/other-part"
}
}