【问题标题】:capture with if-then-else in php regex在 php 正则表达式中使用 if-then-else 捕获
【发布时间】:2013-02-15 17:18:07
【问题描述】:

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

  • 有一个文件名: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) 和扩展名?我认为这与第一组的贪婪有关,但我可能完全错了,即使我是对的,我仍然不知道如何解决它。

感谢您的意见

【问题讨论】:

  • 你用什么语言写这个? Perl?
  • @Imortenson 在 PHP 的 PCRE(perl 兼容的正则表达式)中

标签: regex pcre


【解决方案1】:

在第一个加号之后添加一个问号将使第一个捕获表达式非贪婪。使用您的测试用例,这对我有用:

/^([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"]

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

【讨论】:

  • 非常感谢。这在 PHP 中也适用于所有测试用例。最糟糕的是,事实证明我自己知道如何禁用贪婪,但仍然没有想出它。再次感谢,我会接受答案。
【解决方案2】:

我想这就是你想要的:

/^([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)$/

【讨论】:

  • 感谢您的回复。我刚刚用测试数据“testme_p250.jpg”尝试了这两种方法。整个“testme_p250”与第一组匹配。第二个不匹配任何内容,第三个匹配扩展名。那你觉得哪里出了问题?
  • 你想要怎样的输出?
  • 如问题所述,我希望将所有三个组分开。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多