【问题标题】:Alternative strings in regular expression正则表达式中的替代字符串
【发布时间】:2012-06-22 18:42:25
【问题描述】:

很遗憾,我不得不问这个问题,但是在整个上午都在思考这个问题之后,我放弃了。在线搜索、手册页、文档,似乎都没有给我一个关于我尝试做什么的决定性答案。

寻找 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”这样的图像名称,但这不是我想要允许的。

【问题讨论】:

  • 这对我来说是正确的。您能否包含一个失败的特定代码 sn-p 以及您希望匹配的测试字符串?
  • 您需要在示例正则表达式的最后部分之前添加反斜杠吗? (_MG_|IMG_|DSC_)[0-9]{4}(\-[0-9])? 似乎与您的两个示例都匹配。
  • @andrewsi - 反斜杠无关紧要。
  • @Jens - 正则表达式看起来是正确的,所以问题可能出在其他地方。发布您的 PHP 代码。
  • 这是习惯的力量——我倾向于避开破折号之类的字符,因为它不会造成伤害并且可能会有所帮助。

标签: php regex pattern-matching


【解决方案1】:
<?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 />';
        }
    }
?>

上面的工作对我来说是预期的。

【讨论】:

  • 这是一个稍微不同的表达式:注意末尾的 [-0-9]* 允许 0-n 次出现。应该只允许一个。此外,[-0-9] .. 不确定这是否正确描述了“破折号后跟一个数字”。
  • @Jens 你是对的,[-0-9] 将允许一个字符:-,或一个数字,0 到 9,并且不会指示顺序。
【解决方案2】:

我也跑过这个:

<?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 如果不是所有的 matchers () 都匹配,则返回 false。

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

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

所以您实际上可能希望真正使用 preg_match_all()

【讨论】:

  • 我在原始问题的 EDIT 中发布了一些代码和测试名称。
【解决方案3】:

According to this refiddle,你似乎解决得很好。您可以使用他们的“单元”测试功能附加“应该”和“不应该”匹配场景。当然,那个 refiddle 使用的是 javascript 的正则表达式,但我发现它们实际上是相同的,直到你进入反向引用和环视。

【讨论】:

  • 这实际上是我挠头的部分原因。为了玩弄正则表达式,我使用了“ls | grep -E ...”并且发生了各种奇怪的事情。似乎 grep 正则表达式并不完全是 PHP 正则表达式并不完全是“正则表达式”。因此我很头疼:-)
  • 啊,我明白了。那么让我给你这个链接:rexv.org。该服务允许您选择您的正则表达式引擎和 PREG (PHP PCRE) 是一个选项。
猜你喜欢
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
相关资源
最近更新 更多