正则表达式中的替代字符串


Alternative strings in regular expression

可悲的是,我不得不问这个问题,但是在整整一个上午都在这个问题上点头之后,我放弃了。 在线搜索,手册页,文档,似乎都没有给我一个关于我尝试做的事情的决定性答案。

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

该模式应表示以下内容:字符串以"_MG_"或"IMG_"或"DSC_"开头,后跟四位数字,后跟可选的"-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);

输出:

array(3) {
  [0]=>
  string(10) "IMG_0123-3"
  [1]=>
  string(4) "IMG_"
  [2]=>
  string(2) "-3"
}

似乎没问题,除非我错过了什么,或者除非您指的是如果不是所有匹配器 () 都匹配,preg_match返回 false。

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

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

所以你可能希望真正使用 preg_match_all()

这是您的原始模式,其中包含字符串锚点的开头和结尾以及一些减少模式长度的编辑。

代码:(演示)

var_export(
    preg_grep(
        '/^(?:DSC|[_I]MG)_'d{4}(?:-'d)?$/',
        $array
    )
);