Regex выделить весь текст между тегами - PullRequest
109 голосов
/ 24 августа 2011

Каков наилучший способ выделить весь текст между двумя тегами - например, текст между всеми тегами 'pre' на странице.

Ответы [ 14 ]

135 голосов
/ 24 августа 2011

Вы можете использовать "<pre>(.*?)</pre>", (заменяя pre тем текстом, который вы хотите) и извлечь первую группу (для более конкретных инструкций укажите язык), но это предполагает упрощенное представление о том, что у вас очень простой и правильный HTML.*

Как предлагали другие комментаторы, если вы делаете что-то сложное, используйте HTML-парсер.

112 голосов
/ 02 июня 2013

Метка может быть завершена в другой строке.Вот почему необходимо добавить \n.

<PRE>(.|\n)*?<\/PRE>
17 голосов
/ 01 декабря 2016

Это то, что я бы использовал.

<code>(?<=(<pre>))(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|`~]| )+?(?=(
))

В основном это то, что он делает:

(?<=(<pre>)) Выбор должен начинаться с <pre> тега

(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|~]| ) Это просто регулярное выражение, которое я хочу применить. В этом случае он выбирает букву, цифру, символ новой строки или некоторые специальные символы, перечисленные в примере в квадратных скобках. Символ канала | просто означает « ИЛИ ».

+? Плюс символы состояния для выбора одного или нескольких из вышеперечисленных - порядок не имеет значения. Вопросительный знак изменяет поведение по умолчанию с «жадный» на «неряшливый».

(?=(</pre>)) Выбор должен быть добавлен тегом </pre>

enter image description here

В зависимости от вашего варианта использования может потребоваться добавить некоторые модификаторы, такие как ( i или m )

  • i - без учета регистра
  • m - многострочный поиск

Здесь я выполнил этот поиск в Sublime Text, поэтому мне не пришлось использовать модификаторы в моем регулярном выражении.

Javascript не поддерживает lookbehind

Приведенный выше пример должен хорошо работать с такими языками, как PHP, Perl, Java ... Javascript, однако, не поддерживает lookbehind, поэтому мы должны забыть об использовании (?<=(<pre>)) и искать какой-то обходной путь. Возможно, просто уберите первые четыре символа из нашего результата для каждого выбора, как здесь Регулярное совпадение текста между тегами

Также посмотрите на JAVASCRIPT REGEX ДОКУМЕНТАЦИЮ для не захватывающих скобок

12 голосов
/ 11 ноября 2015

используйте шаблон ниже для получения содержимого между элементами. Замените [tag] фактическим элементом, из которого вы хотите извлечь содержимое.

<[tag]>(.+?)</[tag]>

Иногда теги будут иметь атрибуты, например тег anchor, имеющий href, затем используйте шаблон ниже.

 <[tag][^>]*>(.+?)</[tag]>
6 голосов
/ 24 августа 2011

Вы не должны пытаться анализировать html с помощью регулярных выражений. См. этот вопрос и как это получилось.

В простейших терминах html не является обычным языком, так что вы можете 'Он полностью разбирается с помощью регулярных выражений.

Сказав, что вы можете анализировать подмножества html, когда нет похожих вложенных тегов.Так что, если между тегом и не находится сам этот тег, это будет работать:

preg_match("/<([\w]+)[^>]*>(.*?)<\/\1>/", $subject, $matches);
$matches = array ( [0] => full matched string [1] => tag name [2] => tag content )

Лучшая идея - использовать синтаксический анализатор, такой как DOMDocument, для загрузки html, затем выбрать свой тег иполучите внутренний html, который может выглядеть примерно так:

$obj = new DOMDocument();
$obj -> load($html);
$obj -> getElementByTagName('el');
$value = $obj -> nodeValue();

И так как это правильный синтаксический анализатор, он сможет обрабатывать вложенные теги и т. д.

4 голосов
/ 30 августа 2018

Это, кажется, самое простое регулярное выражение из всего, что я нашел

(?:<TAG>)([\s\S]*)(?:<\/TAG>)
  1. Исключить открывающий тег (?:<TAG>) из совпадений
  2. Включить любые пробельные или непробельные символы ([\s\S]*) в совпадениях
  3. Исключить закрывающий тег (?:<\/TAG>) из совпадений
4 голосов
/ 04 июля 2018

Для исключения тегов-разделителей:

<code>"(?<=<pre>)(.*?)(?=
) "
3 голосов
/ 23 октября 2015

Попробуйте это ....

(?<=\<any_tag\>)(\s*.*\s*)(?=\<\/any_tag\>)
2 голосов
/ 28 августа 2017

var str = "Lorem ipsum text 1
Lorem ipsum
text 2
"; str.replace (/
(.*?)<\/pre>/g, function(match, g1) { console.log(g1); });</code>

Поскольку принятый ответ без кода JavaScript, добавьте, что:

0 голосов
/ 16 октября 2018

preg_match_all(/<pre>([^>]*?)<\/pre>/,$content,$matches) это регулярное выражение будет выбирать все между тегами.не важно, в новой строке (работа с многострочным.

...