匹配贪婪,不同意和其他所有

时间:2014-05-05 18:14:32

标签: regex pcre

给定一个像"/foo/bar/baz/quux"这样的字符串(把它想象成一个unixy系统上文件的路径),我怎么能(如果可能的话)制定一个正则表达式,它给了我所有可能的路径据说包含文件quux

换句话说,在针对给定字符串("/foo/bar/baz/quux")运行正则表达式时,我希望得到结果:

  • "/foo/"
  • "/foo/bar/"
  • "/foo/bar/baz/"

我尝试了以下内容:

  • '/\/.+\//g' - 默认情况下这是贪婪的,匹配"/foo/bar/baz/"
  • '/\/.+?\//g' - 懒惰版,匹配"/foo/"以及"/baz/"

P.S。:我在函数preg_match()中使用PHP中的Perl兼容Regexp,就此而言)

3 个答案:

答案 0 :(得分:2)

此解决方案不会提供您所期望的精确输出,但仍会为您提供非常有用的结果,您可以进行后期处理以获得所需内容:

$s = '/foo/bar/baz/quux';
if ( preg_match_all('~(?=((?:/[^/]+)+(?=/[^/]+$)))~', $s, $m) )
   print_r($m[0]);

Working Demo

<强>输出:

Array
(
    [0] => /foo/bar/baz
    [1] => /bar/baz
    [2] => /baz
)

答案 1 :(得分:2)

费利佩不是在寻找/foo/bar/baz, /bar/baz, /baz,而是在寻找/foo, /foo/bar, /foo/bar/baz

在评论中建立正则表达式想法的一个解决方案,但给出正确的字符串:

  • 反转要匹配的字符串:xuuq/zab/rab/oof/例如在PHP中使用strrev($string )

  • (?=((?<=/)(?:\w+/)+))

  • 匹配

这会给你

zab/rab/oof/
rab/oof/
oof/

然后使用strrev($string)

反转匹配

这会给你

/foo/bar/baz
/foo/bar
/foo

如果您使用的是.NET而不是PCRE,那么您可以从右到左进行匹配,并且可以提供相同的功能。

答案 2 :(得分:0)

完全不同的答案,没有倒转字符串。

(?<=((?:\w+(?:/|$))+(?=\w)))

匹配

foo/
foo/bar/
foo/bar/baz/

但你必须使用C#,它使用变量lookbehind而不是PCRE