我对正则表达式还很陌生,需要一些帮助来解决一些复杂的问题。

我有一个 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) 

Live Demo on Regex101

工作原理:

^[^?]*                  # 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 将失败

Live Demo on Regex101


如果您按照@DevilaNexplode('?', $str) 所说的那样做,这个正则表达式将做您需要的:

\.(jpg|jpeg|gif|png)(\?.*)?$ 

Live Demo on Regex101


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!