在php正则表达式中使用if-then-else捕获

时间:2013-02-15 17:18:08

标签: regex pcre

我很失落的正则表达式。这对我来说只是黑魔法。这就是我需要的:

  • 有一个文件名:some_file.jpg
  • 它可能采用以下格式:some_file_p250.jpg
  • 正则表达式以简单格式匹配文件:/ ^([a-zA-Z_-0-9] +)。(jpg | jpeg | png)$ /
  • 正则表达式以高级格式匹配文件:/ ^([a-zA-Z_-0-9] +)(_ [az]?[0-9] {2,3})。(jpg | JPEG | PNG)$ /

我的问题如下:我如何使“(_ [a-z]?[0-9] {3,4})”部分可选?我试过给第二组添加问号,如下所示:

/^([a-zA-Z_\-0-9]+)(_[a-z]?[0-9]{3,4})?\.(jpg|jpeg|png)$/

即使模式有效,它总是捕获第一组中第二组的内容,并将第二组留空。

如何使这项工作分别捕获文件名,高级部分(_p250)和扩展名?我认为它与第一组的贪婪有关,但我可能完全错了,即使我是对的,我仍然不知道如何解决它。

感谢您的想法

2 个答案:

答案 0 :(得分:0)

我认为这就是你想要的:

/^([a-zA-Z_\-0-9]+)(|_[a-z]?[0-9]{3,4})?\.(jpg|jpeg|png)$/

/^([\d\w\-]+)(|_[a-z]?[0-9]{3,4})\.(jpg|jpeg|png)$/

答案 1 :(得分:0)

在第一个加号后添加问号会使第一个捕捉表达式变得非贪婪。这对我使用你的测试用例很有用:

/^([a-zA-Z_\-0-9]+?)(_[a-z]?[0-9]{3,4})?\.(jpg|jpeg|png)$/

我在Javascript中测试过,而不是PHP,但这是我的测试:

"some_file_p250.jpg".match(/^([a-zA-Z_\-0-9]+?)(_[a-z]?[0-9]{3,4})?\.(jpg|jpeg|png)$/)

和我的结果:

["some_file_p250.jpg", "some_file", "_p250", "jpg"]

根据我的经验,使捕获表达式非贪婪使得正则表达式更加直观,并且通常会使它们按照我期望的方式工作。在你的情况下,它正在做你怀疑的事情;第一个表达式捕获了所有内容,并且从未给第二个表达式提供捕获任何内容的机会。