我肯定我错过了什么。我知道的足够危险。
在我的php代码中,我使用file_get_contents()将文件放入变量中。
然后我循环遍历一个数组,并使用preg_match多次搜索同一个变量。该文件是一个以制表符分隔的txt文件。它在中间做800次,但一次是随机的,它做了一些非常奇怪的事情。
$current = file_get_contents($file);
foreach($blahs as $blah){
$image = 'somefile.jpg';
$pattern = '/https:\/\/www\.example\.com\/media(.*)\/' . preg_quote($image) . '/';
preg_match($pattern, $current, $matches);
echo $matches[0];
}
出于某种原因,有一次它会在两个URL之间切换一个选项卡。当我查看txt文件时,首先列出我要查找的图像,然后是第二个图像,但echo$matches[0]以相反的顺序返回它。它不存在,就像echo$匹配[0]返回它一样。这就像搜索字符串“一两”,而$matches返回“二十一”。
正则表达式引擎正试图帮你一个忙并捕获最长的匹配。两个URL之间的\t
选项卡由匹配代码>(点/任意字符)。
演示:(链接)
$blah='test case: https://www.example.com/media/foo/bar.jpg https://www.example.com/media/cat/fish.jpg some text';
$image = 'fish.jpg';
$your_pattern = '/https:\/\/www\.example\.com\/media(.*)\/'.preg_quote($image).'/';
echo preg_match($your_pattern,$blah,$matches)?$matches[0]:'fail';
echo "\n----\n";
$my_pattern='~https://www\.example\.com/media(?:[^/\s]*/)+'.preg_quote($image).'~';
echo preg_match($my_pattern,$blah,$out)?$out[0]:'fail';
输出:
https://www.example.com/media/foo/bar.jpg https://www.example.com/media/cat/fish.jpg
----
https://www.example.com/media/cat/fish.jpg
结晶。。。
test case: https://www.example.com/media/foo/bar.jpg https://www.example.com/media/cat/fish.jpg some text
// your (.*) is matching ---------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我建议的模式(我可能能够细化的模式,如果您提供的样本字符串)使用(?:[^/\s]*/)
而不是(.*)
。
我的非捕获组如下所示:
(?: #start non-capturing group
[^/\s]* #greedily match zero or more non-slash, non-whitespace characters
/ #match a slash
) #end non-capturing group
+ #allow the group to repeat one or more times
*注1:您可以在我使用\t
的地方使用\s
如果您想更直白一些,我使用的是\s
,因为有效的url无论如何都不应该包含空格。您可以在项目中进行此调整,而不会损失任何准确性。
*注意2:注意,我将模式分隔符更改为~
,这样就不需要在模式内转义/
。