0

我对正则表达式非常迷茫。这对我来说只是黑魔法。这是我需要的:

  • 有一个文件名: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 )$/

我的问题如下:如何使 "(_[az]?[0-9]{3,4})" 部分可选?我尝试向第二组添加一个问号,如下所示:

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

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

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

谢谢你的想法

4

2 回答 2

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)$/
于 2013-02-15T17:27:03.013 回答
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"]

根据我的经验,使捕获表达式不贪婪会使正则表达式更加直观,并且通常会使它们按照我期望的方式工作。就您而言,它正在做您怀疑的事情;第一个表达式是捕捉一切,从不给第二个表达式捕捉任何东西的机会。

于 2013-02-15T17:33:17.510 回答