Как проверить строку содержит только URL изображения

Я пытаюсь оценить строку на основе суффикса файлов, которые она содержит.

Мне нужно различать строки, которые содержат только файлы изображений (.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)

3 ответа

Решение

Прочитав и перечитав ваш вопрос более 20 раз, я думаю, что знаю, что вы пытаетесь сделать.

Для каждой строки (пакета файлов) я запускаю два preg_match() чеки. Тот, который ищет файлы с суффиксом png, gif, jpg, jpeg, или же bmp, Другой, который ищет файлы, которые НЕ имеют суффикса в вышеупомянутом списке.

*нота: (*SKIP)(*FAIL) это метод, используемый для сопоставления и немедленной дисквалификации персонажей в шаблоне.

Код: ( Демонстрация PHP) ( Демонстрация графического шаблона) ( Демонстрация не графического шаблона)

$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
----------------------------------------------------

Регулярное выражение неверно. У тебя есть ) после каждого продления. Это будет работать:

~\.(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';
}

демонстрация

С исправленным регулярным выражением теперь вы можете проверить, содержит ли пакет файлов только изображения, изображения и файлы или только файлы. Мы уже получили первую часть (проверяя, есть ли изображения). С помощью этого регулярного выражения мы можем проверить, есть ли не изображения:

/^(?!.*[.](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 тестов

демонстрация

Вы избегаете своих скобок, поэтому к ним относятся буквально.

Регулярное выражение, которое вы ищете, просто: ~(\.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

Показывает, что будет соответствовать только последняя ссылка.

Это можно увидеть, работая здесь.

Обратите внимание, что вы также, вероятно, захотите i модификатор в конце вашего регулярного выражения, чтобы разрешить расширения файлов также в верхнем регистре. Это может быть сделано с ~(\.png|gif|jpe?g|bmp)$~i,

Другие вопросы по тегам