【问题标题】:Using literal numbers seems to break RegexIterator使用文字数字似乎会破坏 RegexIterator
【发布时间】:2014-03-11 18:13:58
【问题描述】:

当我将数字指定为正则表达式的一部分时,我有一段 PHP 代码停止工作。我确信他们不需要逃脱,但肯定有问题。

代码如下

$dir = new RecursiveDirectoryIterator($IMAGES_DIR);
$iter = new RecursiveIteratorIterator($dir);
$rx = new RegexIterator($iter, $IMG_MASK, RecursiveRegexIterator::GET_MATCH);

$images = array();
foreach ($rx as $r) {
    $images[] = $r[0];
}
var_dump($images);

在与 PHP 文件相同的目录中有一个名为 images 的目录,布局如下:

images/
    1.png
    2.png
    3.png
    test/
        4.png
        5.png
        6.png

在代码中,常量$IMAGES_DIR = 'images/'

$IMG_MASK = /^.+\.png$/ 一切正常时 - 转储包含所有 6 张图像。

$IMG_MASK = /^[1-3]\.png$//^1\.png$//^\1\.png$/(我没想到最后一个会起作用,但试了一下)转储是一个空数组。

不过,在我反对的所有测试人员中,正则表达式似乎都匹配得很好。我错过了什么?

【问题讨论】:

  • 您最终希望$images 数组中有哪些值?这些应该是文件名1.png, 6.png,还是路径./images/1.png, ./images/test/6.png
  • 正确答案是up,所以我想没关系,但我希望$images 包含完整的相对路径。我想感谢您的评论 - 这不是答案,但我觉得即使迈克尔没有发布它,我也可能在回答您时想​​通了。
  • 不客气——这既是我的评论,也是我的回答。我不得不假设你想要相对路径......
  • 原来如此 - 看看你在和谁说话,我!

标签: php regex iterator


【解决方案1】:

这里看起来是$IMAGES_DIR 中的目录本身包含在您的迭代中返回给$r 的模式中。使用您的工作模式,如果您在循环内print_r($r);,您将看到匹配的模式:

array(6) {
  [0]=>
  string(19) "./images/test/4.png"
  [1]=>
  string(19) "./images/test/6.png"
  [2]=>
  string(19) "./images/test/5.png"
  [3]=>
  string(14) "./images/3.png"
  [4]=>
  string(14) "./images/1.png"
  [5]=>
  string(14) "./images/2.png"
}

因此,您需要构建表达式以合并目录,或者忽略它而不锚定^。您尝试的模式与1.png完全 模式匹配,但它正在测试的输入字符串实际上是./images/1.png

我建议使用

$IMG_MASK = '#/[1-3]\.png$#';

此模式不会^ 锚定字符串的开头,而是从数字前的/ 开始匹配。

如果您有兴趣获取完整路径,请将.+ 恢复到开头,并在数字前使用DIRECTORY_SEPARATOR

$IMG_MASK = '#.+' . DIRECTORY_SEPARATOR . '[1-3]\.png$#';

这将匹配任何 (.+) 直到 /(或您的平台的分隔符),然后匹配单个数字和 .png。结果是一个数组,如:

Array
(
    [0] => ./images/3.png
    [1] => ./images/1.png
    [2] => ./images/2.png
)

当然,如果您想要 ./images/test/ 中的这些图像,请调整正则表达式以使用 \d\.png 来匹配任何数字,而不仅仅是 [1-3]

模式

$IMG_MASK = '#.+' . DIRECTORY_SEPARATOR . '\d\.png$#';

...产生:

Array
(
    [0] => ./images/test/4.png
    [1] => ./images/test/6.png
    [2] => ./images/test/5.png
    [3] => ./images/3.png
    [4] => ./images/1.png
    [5] => ./images/2.png
)

【讨论】:

  • 这正是问题所在,谢谢!最糟糕的部分是我暂时考虑了主要目录并将其作为原因丢弃,因为看起来“匹配一切”正则表达式仍然匹配test/ 子目录中的图像。当然它们是匹配的——点匹配目录分隔符。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2011-08-13
  • 2015-04-13
  • 2020-02-22
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多