Php 正则表达式中的可选字符串

Php 正则表达式中的可选字符串,php,regex,pattern-matching,Php,Regex,Pattern Matching,遗憾的是,我不得不问这个问题,但在整个上午都在讨论这个问题之后,我放弃了。在网上搜索,手册页,文档,这些似乎都不能给我一个最终的答案 查找PHP函数的正则表达式,以便将字符串与模式匹配。现在这种模式让我头疼 模式应表示以下内容:字符串以“_MG_uu”或“IMG_uu”或“DSC_u”开头,后跟四位数字,然后是可选的“-N”,其中N是另一位数字。例如,“IMG_0123”或“DSC_9876-3”有效。其他一切都应该被拒绝 我想出了各种各样的模式,但似乎没有一种有效。例如,我试过 (_MG_|I

遗憾的是,我不得不问这个问题,但在整个上午都在讨论这个问题之后,我放弃了。在网上搜索,手册页,文档,这些似乎都不能给我一个最终的答案

查找PHP函数的正则表达式,以便将字符串与模式匹配。现在这种模式让我头疼

模式应表示以下内容:字符串以“_MG_uu”或“IMG_uu”或“DSC_u”开头,后跟四位数字,然后是可选的“-N”,其中N是另一位数字。例如,“IMG_0123”或“DSC_9876-3”有效。其他一切都应该被拒绝

我想出了各种各样的模式,但似乎没有一种有效。例如,我试过

(_MG_|IMG_|DSC_)[0-9]{4}(-[0-9])?
这在不同的变体中,在不同的子表达式周围使用()和撇号,并使用?vs{0,1}等等。(我尝试使用grep,但仍然没有找到匹配项。)是的,我知道我需要为PHP添加“/…/”,但为了可读性,这里我省略了它

我甚至可以用一个表达式来表示,还是必须多次调用匹配函数?如果需要几个匹配项,我最好为自己匹配的这个特定字符串编写一个小型解析器

谢谢

编辑:这是我正在使用的代码

// Iterate over all images in this gallery folder.
if ($h = opendir($dir)) {
  while (($f = readdir($h)) !== false) {

    // Skip images whose name doesn't match the requirement.
    if (0 == preg_match("/(_MG_|IMG_|DSC_)[0-9]{4}(-[0-9]){0,1}/", $f)) {
      continue;
    }

    ...
  }
}
这也允许像“_MG_7020-1-2.jpg”或“_MG_7444-5-6.2.jpg”或“IMG_6543_2_4_tonemapped.jpg”这样的图像名称,但这不是我想要允许的。


<?php

    $array = array('IMG_0123', 'DSC_9876-3', '_MG_1234', 'DSC_fail');

    foreach($array as $arr) {
        if(preg_match("/_MG_|IMG_|DSC_[0-9]{4}[-0-9]*/", $arr)) {
            echo $arr . ' => TRUE <br />';
        } else {
            echo $arr . ' => FALSE <br />';
        }
    }
?>
上述操作对我来说就像预期的一样。

我也运行了以下操作:

<?php
$matches = array();
preg_match('/(_MG_|IMG_|DSC_)[0-9]{4}(-[0-9])?/','IMG_0123-3',$matches );

var_dump($matches);
看起来还可以,除非我遗漏了什么,或者除非你指的是preg_match返回false,如果不是所有的matchers()匹配的话

请注意php文档中preg_match的返回类型:

preg_match()返回模式匹配的次数。这将是0次(无匹配)或1次,因为preg_match()将在第一次匹配后停止搜索。相反,preg_match_all()将一直持续到主题末尾。如果发生错误,preg_match()将返回FALSE


因此,您可能希望真正使用preg_match_all(),事实上,您似乎已经很好地解决了它。您可以使用他们的“单元”测试功能来添加“应该”和“不应该”匹配场景。诚然,refidle使用的是javascript的regex,但我发现它们实际上是完全相同的,直到您进入反向引用和lookarounds。

这在我看来是正确的。是否可以包括一个失败的特定代码段以及您希望匹配的测试字符串?是否需要在示例regexp的最后部分之前添加反斜杠
(\u MG|IMG|DSC|)[0-9]{4}(\-[0-9])?
似乎与您的两个示例都匹配。@andrewsi-反斜杠不重要。@Jens-正则表达式看起来正确,所以问题可能在其他地方。发布你的PHP代码。这是习惯的力量——我倾向于对破折号这样的字符进行转义,理由是它不会有伤害,也可能会有帮助。我在编辑原始问题时发布了一些代码和测试名称。这是一个稍微不同的表达:注意结尾处的[-0-9]*允许出现0-n。应该只允许一个。而且,[-0-9]。。不确定这是否正确描述了“破折号后跟一个数字”。@Jens你是对的,[-0-9]将允许一个字符:a
-
,或一个数字,0到9,并且不会指示顺序。实际上,这就是我搔头的部分原因。为了玩regex,我用了“ls | grep-E…”并且有各种各样的奇怪发生。似乎grep regexp不是很好,PHP regexp也不是很“regexp”。因此我头痛:-)啊,我明白了。那么让我给你这个链接:。该服务允许您选择regex引擎,PREG(phppcre)是一个选项。
array(3) {
  [0]=>
  string(10) "IMG_0123-3"
  [1]=>
  string(4) "IMG_"
  [2]=>
  string(2) "-3"
}