我对正则表达式还很陌生,需要一些帮助来解决一些复杂的问题。
我有一个 URL 列表,它们也可能在一个数组中,如下所示:
$urls = array(
"http://example.com/page.php",
"http://example.com/page.php?key=value",
"http://example.com/image.jpg",
"http://example.com/image.jpg?key=value" ...
我想遍历数组(使用 foreach
就够简单了),如果 URL 指向一个图像文件,则每个字符串都返回 true。我有以下正则表达式:
"#\.(jpg|jpeg|gif|png)$# i"
...但它似乎只返回 true 是字符串以给定的图像扩展名之一结尾。我需要补偿两个因素:1. 如果字符串末尾有 URL 查询字符串(即 ?key=value
)以及扩展名(例如 jpg
) 实际上是非图像文件的查询字符串的一部分,例如:
http://example.com/page.php?image=file.jpg
应该返回 false,因为 URL 指向的是 PHP 文件,而不是 jpg
感谢您的帮助!
请您参考如下方法:
完整的正则表达式版本
实际上,这是一个完整的 RegEx 版本:
^[^?]*\.(jpg|jpeg|gif|png)
工作原理:
^[^?]* # Removes ?foo=bar&baz=foo
\.(jpg|jpeg|gif|png) # Image Extension
第一部分选择直到 ?...
的所有内容。它是等同于从 explode('?', $str)
中选择第一项的 RegEx。第二部分和你的一样,去掉了$
(因为字符串的结尾可能是?
之后的变量)
处理以下异常文件扩展名的情况,例如:
test.jpgfoo
test.pngbar
test.jpg.nope
image.jpg-test.php
image.jpg_test.php
在最后添加一个Negative Lookahead,(?![\w.\-_])
:
^[^?]*\.(jpg|jpeg|gif|png)(?![\w.\-_])
这将确保在接受的文件扩展名之后没有字母、另一个扩展名、.
、-
或 _
。如果有,则 RegEx 将失败
如果您按照@DevilaN 和explode('?', $str)
所说的那样做,这个正则表达式将做您需要的:
\.(jpg|jpeg|gif|png)(\?.*)?$