Регулярное выражение для извлечения числового значения при изменении позиции в строке переменной

#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, описывающую те модификаторы, которые вам не нужны.