当我将数字指定为正则表达式的一部分时,我有一段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$/
(我没想到最后一个工作,但是给它一个镜头)时,转储是一个空数组。
正如我所反对的所有测试人员中的正则表达式似乎都很好。我错过了什么?
答案 0 :(得分: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
)