PHP preg_grep反向匹配模式

时间:2015-10-22 18:39:09

标签: php regex

我构建了一个简单的代码,用于解析多个磁盘中的所有音乐文件夹,并将列表放入数组中。

文件夹名称在类别时以多个空格开头,当它们是"最终文件夹"时会有一个空格。例如。看到这个结构:

[0] => /Volumes/SAMPLES/  VOCALS/
[1] => /Volumes/SAMPLES/  VOCALS/  AFRICA/
[2] => /Volumes/SAMPLES/  VOCALS/ AcmeInc Club Vocals/
[3] => /Volumes/SAMPLES/  VOCALS/ AtomicInc Dance Vocals/
[4] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ AfroInc Zulu Vocals/
[5] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/
[6] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/SampleInc_Warriors_Ululation/
[7] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/SampleInc_Warriors_Drums/

依旧......我只需要选择最终文件夹并尝试几种贪婪和非贪婪模式的组合,从最终$开始 例如。以下路径不起作用:

$pattern = "#\/ ([:alnum:]+?)/$#i";
$matches  = preg_grep ($pattern, $root);

预期结果应该是:

[3] => /Volumes/SAMPLES/  VOCALS/ AcmeInc Club Vocals/
[4] => /Volumes/SAMPLES/  VOCALS/ AtomicInc Dance Vocals/
[5] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ AfroInc Zulu Vocals/
[6] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/

相反,我得到所有的文件夹或没有或孤儿。请考虑像&或者特殊的字符!可以在文件夹名称中。感谢您的建议,3天,尝试了一切,绝望,谢谢!

2 个答案:

答案 0 :(得分:3)

这是一个有效的正则表达式:

'~/(?:  +[^/\s]+)*/ [^/\s]+(?: +[^/\s]+)*/$~'

请参阅regex demo

匹配:

  • /(?: +[^/\s]+)* - 非最终子文件夹(/,然后超过1个空格,1个或多个字符而不是空格或/
  • / - 带有空格的正斜杠
  • [^/\s]+ - 除空格或正斜杠以外的1个或多个字符
  • (?: +[^/\s]+)* - 0个或更多个序列...
    • + - 一个或多个常规空格
    • [^/\s]+ - 除空格或正斜杠以外的1个或多个字符
  • / - 正斜杠
  • $ - 字符串结尾

请参阅PHP code demo

$ar = array("/Volumes/SAMPLES/  VOCALS/", 
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/",
    "/Volumes/SAMPLES/  VOCALS/ AcmeInc Club Vocals/",
    "/Volumes/SAMPLES/  VOCALS/ AtomicInc Dance Vocals/",
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/ AfroInc Zulu Vocals/",
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/",
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/SampleInc_Warriors_Ululation/",
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/SampleInc_Warriors_Drums/",
    "/Volumes/SAMPLES/  VOCALS/  AFRICA/ AfroInc Zulu Vocals/ Folder1/"
    );
$n = preg_grep('~/(?:  +[^/\s]+)*/ [^/\s]+(?: +[^/\s]+)*/$~', $ar);
print_r($n);

结果:

Array
(
    [2] => /Volumes/SAMPLES/  VOCALS/ AcmeInc Club Vocals/
    [3] => /Volumes/SAMPLES/  VOCALS/ AtomicInc Dance Vocals/
    [4] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ AfroInc Zulu Vocals/
    [5] => /Volumes/SAMPLES/  VOCALS/  AFRICA/ SampleInc Warriors/
)

答案 1 :(得分:1)

您只需要确保空格后面的下一个字符也不是空格。

$result = preg_grep('~/ [^/ ][^/]*/\z~', $root);

模式细节:

/          # literal slash
[ ]        # literal space
[^/ ]      # a character except a slash or a space
[^/]*      # zero or more characters that are not a slash
/          # literal slash
\z         # end of the string

demo