#php #regex
#php #регулярное выражение
Вопрос:
Как я могу извлечь выделенную жирным шрифтом числовую часть строки, когда большая часть строки может измениться? /data/ всегда присутствует и сопровождается соответствующей переменной числовой частью (в данном случае 123456).
Различное местоположение содержимого HTTPS://example.com/api/result/13548/data/123456 различное содержимое, включая белые пространства и новые строки8484
$str = "differentcontentLocationhttps://example.com/api/result/13548/data/123456differentstuffincludingwhitespacesandnewlines8484";
$str2 = "differentcontentLocationhttps://example.com/api/result/13548/data/123456";
В этом примере мне нужно 123456
. Единственными постоянными частями в строке являются /data/
и, возможно, первая часть URL-адреса, например https://.
preg_match("@/data/([0-9] )([^0-9] )@siU", $str, $matches);
Приводит к Array ( [0] => /data/123456d [1] => 123456 [2] => d )
тому, что было бы приемлемо. Но если после соответствующей числовой части ничего нет, например, в $str2
, это выражение завершается ошибкой. Я пытался сделать конечную часть необязательной с preg_match("@/ads/([0-9] )(([^0-9] )?)@siU", $x, $matches);
помощью , но это тоже не удается; возвращается только первое число числовой части.
Комментарии:
1. Используйте
@/data/([0-9] )@i
.U
Модификатор на самом деле вам не помогает и делает регулярное выражение более сложным, чем оно должно быть. См. ideone.com/IUQMBS
Ответ №1:
Модификатор U
замены жадности делает все жадные подшаблоны здесь ленивыми, вы должны удалить его вместе с ([^0-9] )
. Вам также не нужен модификатор DOTALL, потому .
что в вашем шаблоне нет такого, поведение которого можно было бы изменить с помощью этого s
флага.
preg_match("@/data/([0-9] )@i", $str, $matches);
Теперь шаблон будет соответствовать:
/data/
— последовательность буквенных символов([0-9] )
— Группа 1, содержащая 1 цифр (такая же, как )(d )
Смотрите демонстрацию PHP.
$str = "differentcontentLocationhttps://e...content-available-to-author-only...e.com/api/result/13548/data/123456differentstuffincludingwhitespacesandnewlines8484";
$str2 = "differentcontentLocationhttps://e...content-available-to-author-only...e.com/api/result/13548/data/123456";
preg_match("@/data/([0-9] )@i", $str, $matches);
print_r($matches); // Array ( [0] => /data/123456 [1] => 123456 )
preg_match("@/data/([0-9] )@i", $str2, $matches2);
print_r($matches2); // Array ( [0] => /data/123456 [1] => 123456 )
Комментарии:
1. После вашего первого комментария я понял, что модификатор U вызывает проблемы. Ваш шаблон отлично работает в реальном мире. Спасибо 🙂
2. ДА. Я также добавил ссылки на документацию SO Regex, описывающую те модификаторы, которые вам не нужны.