【问题标题】:PHP regular expression to detect if url is to an image filePHP正则表达式检测url是否为图像文件
【发布时间】:2016-07-27 23:05:19
【问题描述】:

我对正则表达式非常陌生,需要一些复杂的帮助。

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

感谢您的帮助!

【问题讨论】:

  • 仅供参考:除非您实际检索它,否则您无法知道page.php 返回图像
  • 没关系,我可以检查内容类型作为备用,谢谢!
  • @Sjon:一个愉快的中间立场可能是一个 HEAD 请求,信任 Web 服务器分配正确的 Content-Type。 OP:除非您提出请求,否则您不会拥有 Content-Type,这就是他的意思。
  • 好吧,我不喜欢这里的单一正则表达式解决方案:'~^(?!.*\?.*(\.(?:jpg|jpeg|gif|png)\b)).*(?1)(?:$|\?)~'
  • 检查 tools.ietf.org/html/rfc3986#page-50 以了解如何正确解析 URL。在您的情况下,$6 必须以您声明的扩展名结尾。

标签: php regex url


【解决方案1】:

完整的正则表达式版本

其实这里有一个完整的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) 所说的那样做,此 RegEx 将满足您的需求:

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

Live Demo on Regex101

【讨论】:

  • @DevilaN 我为那些不寻常的情况添加了更新。只需在末尾加上(?!\w),以确保在接受的文件扩展名之后没有更多字母
  • @DevilaN 谢谢,也解决了这个问题!
  • @DevilaN 说真的! ;) 我什至不认为这是一个有效的文件扩展名,但我已经修复了它,以及任何 _!还有其他人吗?
  • @DevilaN 哇!这需要很长时间才能包括在内!如果 OP 想要这样做,他可以自己将 then 添加到 Negative Lookahead 中。 ;)。等等,我现在看到你的解决方案更有意义了!
【解决方案2】:

你的正则表达式没问题,但是你需要去掉 ?something=something 只需爆炸(“?”,$string);并使用仅包含带有文件名的 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"
);

function isImage($l) {
    $arr = explode("?", $l);
    return preg_match("#\.(jpg|jpeg|gif|png)$# i", $arr[0]);
}
foreach ($urls as $url) {
    echo $url . ": " .(isImage($url) ? "true" : "false") . "\n";
}

结果是:

http://example.com/page.php: false
http://example.com/page.php?key=value: false
http://example.com/image.jpg: true
http://example.com/image.jpg?key=value: true

如果你想要纯正则表达式解决方案,那么:

function isImage($l) {
    return preg_match("/^[^\?]+\.(jpg|jpeg|gif|png)(?:\?|$)/", $l);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多