Как вырезать определенный текст в regex?

179
25 ноября 2017, 11:17

Есть строка My {site} как оставить только site ? А вот если нужно еще так: my {zip} i {ooi} выбрать zip и ooi

Answer 1

Чтобы извлечь текст между одним символом/подстрокой и ближайшим к нему другим символом/подстокой, обычно используется .*?, точка с ленивым квантификатором. Если между этими символами/подстроками есть знак перехода на новую строку, нужно использовать модификатор s (DOTALL, изменяет поведение точки в шаблоне для нахождения символов перехода на новую строку). Чтобы не приходилось добавлять этот модификатор и получить более эффективное выражение, можно прибегнуть к исключающим символьным классам, [^}]* — 0 и более символов, отличных от }. В случае использования многосимвольной подстроки в качестве начального разделителя такой подход, к сожалению, не сработает.

Кроме того, существует несколько разновидностей шаблонов, извлекающих тексты между двумя фигурными (да и другими) скобками. Рассмотрим варианты, из которых можно выбрать наиболее подходящие для данной и других ситуаций:

  • Между ближайшими {...} есть любые знаки: '~{(.*?)}~s' / '~{([^}]*)}~'
  • Между ближайшими {...} есть любые знаки, кроме самих скобок: '~{([^{}]*)}~'
  • Между ближайшими {...} есть только одно слово: '~{(\w+)}~u'
  • Между {...} может быть очень много вложенных фигурных скобок: '~{((?:[^{}]++|(?R))*)}~' (тут выражение находит {, после которой следует 0 и более повторов 1+ знаков, отличных от { и }, или самого шаблона целиком (т.е. рекурсивно ищет вхождения всего шаблона), а затем закрывающую }).

Обратите внимание, что модификатор u нужен в тех случаях, когда необходима поддержка строк Юникода.

Теперь, как эти выражения использовать? В PHP есть две основные функции для извлечения текста с помощью регулярного выражения, preg_match (ищет первое совпадение) и preg_match_all (ищет все непересекающиеся совпадения). В данном случае необходимо использовать вторую функцию:

$s='my {zip} i {ooi} o {тут
новая строка} {отлично, да!}  {ну {да!}
{Вот это {Вот это {Вот это } да!} нет!}';
if (preg_match_all('~{([^{}]*)}~', $s, $matches)) {
    print_r($matches[1]);
}
// => Array ( [0] => zip [1] => ooi [2] => тут
//   новая строка [3] => отлично, да! [4] => да! [5] => Вот это )

См. PHP-демо

  • $matches[0] содержит все найденные совпадения, вместе со скобками.
  • $matches[1] содержит все значения, захваченные первой захватываемой группой, которая задана в каждом из вышеперечисленных регулярных выражений, т.е. весь текст внутри скобок.
Answer 2

Вот этой регуляркой можете взять то что вам нужно.

#\{(.*?)\}#m

А пример работы регулярки можете смотреть тут.

Эта регулярка берет все что будет в ковычках ({})

Пример работы на php

<?php 
  $string = 'My {si-te}';
  $pattern = '/\{(.*?)\}/m';
  preg_match($pattern, $string, $m);
  print_r($m);
?>

Результат.

Array
(
  [0] => {si-te}
  [1] => si-te
)
Answer 3

https://regex101.com/r/lGIgBZ/2

\{\w+\} - в принципе, этой регулярки должно хватить.

READ ALSO
Подгрузка стилей

Подгрузка стилей

Есть сайт что то вроде мультилендоса, к посадочным страницам через "require" или "include" подключается из динамической папки(для каждой страницы...

206
Пояснение строки в Yii2(PHP)

Пояснение строки в Yii2(PHP)

Здравствуйте

154
MVC, работа с моделью

MVC, работа с моделью

Дело было вечером, делать было нечегоДля расширения кругозора решил написать мини-фреймворк на чистом PHP

183
Функциональное тестирование в Symfony 1

Функциональное тестирование в Symfony 1

Доброе время суток, не подскажите, как проверить функциональным тестом что на странице вывелся нужный контент? Я пишу тест

158