【问题标题】:How to check string contains only image urls如何检查字符串仅包含图片网址
【发布时间】:2018-02-23 02:13:10
【问题描述】:

我正在尝试根据它包含的文件的后缀来评估一个字符串。

我需要区分仅包含图像文件(.png.gif.jpg.jpeg.bmp)的字符串和同时包含图像和非图像文件的字符串。

我做错了什么?

if (preg_match('~\.(png\)|gif\)|jpe?g\)|bmp\))~', $data->files)) {
  echo 'image only;'
} else {
  echo 'image + other types';
}

包含混合物的示例字符串:

filename 1 (https://example.com/test.pdf),
filename 2 (https://example.com/cool_image.jpg),
filename 3 (https://example.com/other-file.docx)

仅包含图像的示例字符串:

filename 1 (https://example.com/another.png),
filename 2 (https://example.com/cool_image.jpg)

【问题讨论】:

  • 可能你需要'/\\.(png|gif|jpe?g|bmp)$/'
  • 您不需要正则表达式,有时带有 jgp、bmp 的扩展名也可能不是有效的图像
  • @sumit 虽然这项任务可以在没有正则表达式的情况下完成,但它是评估字符串的最明智和直接的工具。

标签: php regex preg-match preg-match-all image-file


【解决方案1】:

正则表达式错误。每次分机后都有)。这将起作用:

~\.(png|gif|jpe?g|bmp)~i

完整示例:

<?php
if (preg_match('~\.(png|gif|jpe?g|bmp)~i', "https://example.com/test.png")) {
  echo 'image only';
}
else {
  echo 'image + other types';
}

Demo

使用更正的正则表达式,现在您可以检查这批文件是否仅包含图像、图像和文件,或者仅包含文件。我们已经完成了第一部分(检查是否有图像)。使用这个正则表达式,我们可以检查是否有非图像:

/^(?!.*[.](png|gif|jpe?g|bmp))(?:.*$|,)/im

它使用否定的前瞻来断言行中的扩展名不匹配。最后有一个非捕获组来检查行尾或逗号(以符合您的格式)。

所以最后,检查两个正则表达式并查看每个批次真正包含的内容:

$files=[
    'Non-Images Only'=>'filename 1 (https://example.com/test.exe)',
    'Mixed-Type'=>'filename 1 (https://example.com/test.pdf),
filename 2 (https://example.com/cool_image.jpg),
filename 3 (https://example.com/other-file.docx),
filename 4 (https://example.com/nice_image.png)',
    'Images-Only'=>'filename 1 (https://example.com/another.png),
filename 2 (https://example.com/cool_image.jpg))'];
foreach ($files as $type => $batch) {
    echo "Batch: ".$batch.PHP_EOL;
    echo "Expecting: ".$type.PHP_EOL;
    $images = preg_match('/\.(png|gif|jpe?g|bmp)/im', $batch);
    $nonImages = preg_match('/^(?!.*[.](png|gif|jpe?g|bmp))(?:.*$|,)/im', $batch);
    $result = "";
    if ($images && $nonImages) {
        $result = "Mixed-Type";
    }
    else {
        if ($images) {
            $result = "Images-Only";
        }
        else {
            $result = "Non-Images Only";
        }
    }
    echo "Result: ".$result.PHP_EOL;
    echo PHP_EOL;
}

注意:使用了@mickmackusa 的测试列表

Demo

【讨论】:

  • @mickmackusa 没有看到这个。你能进一步澄清这个问题吗?正则表达式成功检查字符串是否包含图像扩展名(如果文件实际上是图像是另一个问题......)
  • @mickmackusa 我明白了。会试一试的。
  • 感谢更新。现在,你的回答比我的模式慢两倍,而赞成票是我的 4 倍。这肯定会让未来的研究人员感到困惑。你介意点赞我的回答吗?
  • 您需要备份您的声明:)。 Mine answeryour answer。它们看起来几乎一样。当接受的答案是你的答案时,赞成票将如何混淆研究?我当然不介意支持你的回答,尽管我个人不喜欢要求支持的人。
  • 我的手指和脚趾都用完了。
【解决方案2】:

在阅读和重新阅读您的问题 20 多次之后,我想我知道您要做什么。

对于每个字符串(文件批次),我运行两个 preg_match() 检查。查找后缀为pnggifjpgjpegbmp 的文件。另一个在上述列表中寻找没有后缀的文件。

*注意:(*SKIP)(*FAIL) 是一种用于匹配并立即取消模式中字符资格的技术。

代码:(PHP Demo) (Image Pattern Demo) (Non-Image Pattern Demo)

$tests=[
    'Non-Images Only'=>'filename 1 (https://example.com/test.exe)',
    'Mixed-Type'=>'filename 1 (https://example.com/test.pdf),
filename 2 (https://example.com/cool_image.jpg),
filename 3 (https://example.com/other-file.docx),
filename 4 (https://example.com/nice_image.png)',
    'No Files'=>'filename 1 (),
filename 2 ()',
    'Images-Only'=>'filename 1 (https://example.com/another.png),
filename 2 (https://example.com/cool_image.jpg))'];

$image_pattern='~\.(?:png|gif|jpe?g|bmp)\),?$~im';
$non_image_pattern='~\.(?:(?:png|gif|jpe?g|bmp)(*SKIP)(*FAIL)|[^.)]+)\),?$~im';

foreach($tests as $type=>$string){
    echo "\t\tAssessing:\n---\n";
    echo "$string\n---\n";
    echo "Expecting: $type\n";
    echo "Assessed as: ";
    $has_image=preg_match($image_pattern,$string);
    $has_non_image=preg_match($non_image_pattern,$string);
    if($has_image){
        if($has_non_image){
            echo "Mix of image and non-image files";
        }else{
            echo "Purely image files";
        }
    }else{
        if($has_non_image){
            echo "Purely non-image files";
        }else{
            echo "No files recognized";
        }
    }
    echo "\n----------------------------------------------------\n";
}

输出:

        Assessing:
---
filename 1 (https://example.com/test.exe)
---
Expecting: Non-Images Only
Assessed as: Purely non-image files
----------------------------------------------------
        Assessing:
---
filename 1 (https://example.com/test.pdf),
filename 2 (https://example.com/cool_image.jpg),
filename 3 (https://example.com/other-file.docx),
filename 4 (https://example.com/nice_image.png)
---
Expecting: Mixed-Type
Assessed as: Mix of image and non-image files
----------------------------------------------------
        Assessing:
---
filename 1 (),
filename 2 ()
---
Expecting: No Files
Assessed as: No files recognized
----------------------------------------------------
        Assessing:
---
filename 1 (https://example.com/another.png),
filename 2 (https://example.com/cool_image.jpg))
---
Expecting: Images-Only
Assessed as: Purely image files
----------------------------------------------------

【讨论】:

  • 非常感谢。很抱歉,我无法很好地解释。英语不是我的主要语言。我通过 Airtable 的 api 获取数据。我必须以某种方式区分该字段是否包含非图像链接。
  • 不用担心。我很乐意提供帮助。
【解决方案3】:

你正在逃避你的括号,所以他们得到了字面上的对待。

您正在寻找的正则表达式很简单:~(\.png|gif|jpe?g|bmp)$~

if (preg_match('~(\.png|gif|jpe?g|bmp)$', $data->files)) {
  echo 'image only;'
}
else {
  echo 'image + other types';
}

注意,末尾的$ 表示字符串的结尾很关键;没有它,字符串的任何部分都将是有效匹配。因此,.jpg.exe 等文件将被视为“图像”。

针对字符串运行正则表达式(\.png|gif|jpe?g|bmp)$

https://example.com/test.pdf
https://example.com/other-file.docx
https://example.com/cool_image.jpg.exe
https://example.com/cool_image.jpg

表明只有最后一个链接会匹配。

这可以看到 here

请注意,您可能还想在正则表达式的末尾添加i 修饰符,以允许使用大写的文件扩展名。这可以通过~(\.png|gif|jpe?g|bmp)$~i 完成。

【讨论】:

  • "你的正则表达式应该用正斜杠 (/) 而不是波浪线 (~)" 为什么?
  • 我已将其删除。我已经习惯了分隔符很重要的其他语言,但根据 PCRE 有一个波浪号很好:)
  • 你说的是JS吗?我从未注意到有人仅限于使用/。在 PCRE 中,您几乎可以使用任何您想要的东西:“分隔符可以是任何非字母数字、非反斜杠、非空白字符”。
  • @ObsidianAge 请给我看一个不区分大小写的模式修饰符。 (只是为了它)
  • @mickmackusa - 为了有一个不区分大小写的修饰符,你只需要在正则表达式的末尾加上一个i 修饰符。所以~(\.png|gif|jpe?g|bmp)$~i 可以工作:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 2018-09-03
  • 2017-12-16
  • 1970-01-01
  • 2010-12-19
相关资源
最近更新 更多