Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Регулярные выражения в php и других языках.Регулярные выражения: поиск с инверсией

Лекция



Привет, Вы узнаете о том , что такое регулярные выражения в php , Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое регулярные выражения в php , регулярные выражения, поиск с инверсией , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .

Понадобилось мне найти все слова в предложении, кроме определенных слов. Например, в предложении ‘Many modern computing systems provide wildcard characters in matching filenames from a file system.‘ найти все, кроме слов computing и matching.

Испытуемый текст: ‘Many modern computing systems provide wildcard characters in matching filenames from a file system.‘

Регулярное выражение: ‘/\\b(?!(?:computing|matching)\\b)w+\\b/’

Результат: перечень всех слов за исключением computing и matching.

где,

\\b – граница слова

w – набор символов [A-Za-z0-9_]

?: – несохраняющие скобки, т.е. все что внутри группирующих скобок не будет включено в результат

?! – поиск с инверсией , т.е. то, что внутри будет исключено из совпадения

Вообще комбинация ?! называется негативная опережающая проверка и относится к одному из четырех видов позиционных проверок:

Тип Регулярное
выражение
Успешна,
если подвыражение…
Позитивная ретроспективная проверка (?<=..) Может совпасть слева
Негативная ретроспективная проверка (?<!–..) Не может совпасть слева
Позитивная опережающая проверка (?=..) Может совпасть справа
Негативная опережающая проверка (?!..) Не может совпасть справа

Для проверки работы можно воспользоваться:

  • RegExr – online инструмент для проверки регулярных выражений.
  • rejex.heroku.com - еще один online отладчик regexp'ов.
  • strfriend.com - визуализатор регулярных выражений.
  • pythex.appspot.com

Расширение для FireFox Regular Expressions Tester

Полезный материл – RegexAdvice Forums – форум по регулярным выражениям.

Пока читал бестлер про регулярным выражениям – Дж. Фридл – регулярные выражения  узнал две интересные вещи:

  • по спецификации POSIX существует два диалекта регулярок BRE и ERE
  • две базовые технологии, на базе которых строится механизм регулярных выражений: НКА и ДКА

BRE (basic regular expressions) – базовые регулярные выражения

ERE (extened regular expressions) – расширенные регулярные выражения

НКА (недетерминированный конечный автомат) – механизм управляется регулярным выражением

ДКА (детерминированный конечный автомат) – механизм управляется текстом

Поддержка диалектами разных метасимволов

Метасимволы BRE ERE
Точка, ^, $, [..], [^..] Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
Произвольное число * *
Квантификаторы + и ?   +?
Интервальный квантификатор {мин, макс} {мин, макс}
Группировка (..) (..)
Применение квантификаторов к скобкам Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
Обратные ссылки 1..9  
Конструкция выбора   Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией

Краткая таблица сравнения ДКА и НКА

параметры ДКА НКА
поддержка обратных ссылок Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
сохранение текста в круглых скобках Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
быстрый поиск совпадений Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
быстрая компиляция Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией
меньшие затраты памяти Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией Регулярные выражения в php  и других языках.Регулярные выражения: поиск с инверсией

 

 

 

 

Примечание редакции. Об этом говорит сайт https://intellect.icu . Существует много диалектов языка регулярных выражений. Выражения из этой статьи используют синтаксис, принятый в Perl, в том числе недоступные в других диалектах функции. Похожий диалект вне языка Perl известен как "Perl-совместимые регулярные выражения" (PCRE, Perl-Compatible Regular Expressions).

В большинстве текстовых редакторов можно провести поиск по слову, его части и учитывать регистр. Чаще всего, этих возможностей достаточно, поскольку приходится обрабатывать относительно простые тексты - мозг человека сразу оценивает полученное совпадение и принимает решения.

Рано или поздно наступает момент, когда человеческих ресурсов не хватает для обработки всей поступающей информации, или требуется ввести полностью автоматизированную обработку данных, например, для публикации новостей из разных источников на своем сайте. Здесь вступают в работу автоматизированные системы, в которых нашли широкое применение регулярные выражения. Их использование позволяет в десятки раз уменьшить объем кода, необходимого для обработки текстов. При первом знакомстве регулярные выражения вызывают самые различные реакции, но общее в них то, что человека отталкивает сложность понимания смысла этих «высказываний». Данная статья призвана объяснить, как прочитать выражение и понять его смысл.

Термины

  • оператор – символы, используемые в регулярных выражениях; они управляют поиском, но не участвуют в совпадении.
  • совпадение – один или больше символов и операторов регулярного выражения, которые совпали с проверяемым текстом.
  • квантификатор – оператор регулярного выражения, определяющий количество экземпляров повторяющегося совпадения.
    • жадный (другое определение - «максимальный») – захватывает все доступные совпадения, после чего может их возвратить, если потребуется операторам справа. По умолчанию, все квантификаторы - «жадные».
    • не жадный (другое определение - «минимальный») – захватывает совпадение только в том случае, если нет совпадения справа.
    • захватывающий – жадный, никогда не возвращает захваченные совпадения.
  • последовательное совпадение – последовательность одинаковых совпадений.

Словарь операторов

  • символы
    • <символ> – печатный символ: буквы, цифры, знаки препинания и т.д.
    • . – произвольный символ
    • подстрока – литеральный (такой, в котором нет операторов) набор символов.
  • управление совпадением (квантификаторы)
    • – ноль или больше последовательных совпадений
    • – одно или больше последовательных совпадений
    • – ноль или одно совпадение
    • *? – не жадные ноль или больше последовательных совпадений
    • +? – не жадные одно или больше последовательных совпадений
    • *+ – захватывающие ноль или больше последовательных совпадений
    • ++ – захватывающие одно или больше последовательных совпадений
    • {n1,n2} – от n1 до n2 последовательных совпадений
    • {n} – ровно n совпадений
  • формирование последовательности – совпасть может только вся последовательность
    • ( – начнем захватывать совпадения в последовательность и сохраним ее в памяти (сохраняющие скобки)
    • (?: – начнем захватывать совпадения в последовательность, но не сохраняем ее (несохраняющие скобки)
    • ) – завершим захватывать совпадения.
    • | – альтернативная последовательность при отсутствии совпадения с последовательностью слева
  • наборы символов – совпадает любой из символов
    • [ – откроем набор символов
    • ] – закроем набор символов
    • - – укажем диапазон символов
    • ^ – набор содержит все символы, кроме перечисленных
  • позиционная проверка
    • (?= – начнем проверку на наличие совпадения справа
    • (?! – начнем проверку на отсутствие совпадения справа
    • (?< = – начнем проверку на наличие совпадения слева
    • (?<! – начнем проверку на отсутствие совпадения слева
    • ) – завершим проверку
  • ссылки на предыдущие совпадения
    • \0..\9 – порядковый номер последовательности в сохраняющих скобках

Так выглядит перевод конструкций регулярных выражений на «человеческий» язык. В дальнейшем, при разборе примеров, я дам им развернутое описание.

Чтение и написание регулярных выражений

Проговаривание вслух и запись правил - основная проблема, возникающая при освоении техники разбора текста с помощью регулярных выражений. При отсутствии опыта трудно сформулировать словесную запись правил. Тем не менее - это наиболее эффективный путь составления регулярных выражений.

Основным правилом при составлении регулярных выражений является их запись в развернутом виде на листе бумаги или на экране. Так легче всего определить, насколько верно будет обработан текст. Другое правило заключается в составлении выражения от общего к частному. При его соблюдении значительно сокращается время написания выражения и количество ошибок.

Сформулируем условия для успешного составления регулярного выражения

  1. У выражения должна быть «литературная» форма.
  2. Словесное описание должно быть логичным.
  3. Составление выражения должно идти:
    1. от простого к сложному.
    2. от общего к частному.

Несмотря на трудоемкость подобной записи, она повышает скорость разработки и отладки правил разбора текстов и эффективность их применения.

Пример составления выражения

Задача

Выделить в HTML разметке содержимое определенных блоков с установленными атрибутами:

  • абзац (тег <p>) с CSS классом content
  • элемент списка (тег <li>) с CSS классом content
<p>Абзац 1</p>
<p class="content">Абзац 2</p>
<ul>
   <li>Элемент 1</li>
   <li class="content">Элемент 2</li>
</ul>
<p class="content">Абзац 2</p>
<li class="content">Элемент 2</li>

Последовательность решения

  1. Составим регулярное выражение для выделения всех тегов.
  2. Дополним его для выделения только парных тегов.
  3. Дополним его для выделения только заданных тегов.
  4. Напишем выражение для поиска пар 'имя_атрибута = «значение»'.
  5. Дополним основное выражение для выделения заданных тегов с определенными атрибутами.
  6. Добавим модификаторы поиска.

Обычно начинают одновременно производить все 6 шагов что вызывает серьезные проблемы при отладке. Я предлагаю действовать постепенно. Шаг за шагом.

Приведу решение сразу:

#<(p|li)\s+[^>]*?class\s*=\s*(['"])content\2[^>]*>((?:(?!</\1>).)*)</\1>#is

Согласитесь, выглядит оно почище «китайской грамоты». Тем не менее, следуя описанию, Вы увидите, что все не так уж и сложно.

Итак, начнем:

Шаг 1. Выделение всех тегов

Запишем правила разбора по-русски:

  1. Найдем подстроку '<'
  2. Начнем захватывать символы в последовательность
    1. Захватим одну или более букву алфавита
  3. Завершим захватывать совпадения
  4. Захватим 0 или более символов, не совпадающих с набором символов '>'
  5. Захватим подстроку '>'
  6. Начнем захватывать символы в последовательность
    1. Захватим 0 или более символов, не совпадающих с набором символов '>'
  7. Завершим захватывать совпадения

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

  1. <
  2. (
    1. \w+
  3. )
  4. [^>]*
  5. >
  6. (
    1. [^<]*
  7. )

У нас получилось следующее выражение:

<(\w+)[^>]*>([^<]*)

Оно имеет 2 недостатка:

  1. захватывает все теги, а не только парные.
  2. некорректно отрабатывает вложенные теги.

Шаг 2. Выделение парных тегов

Запишем правила разбора формальным языком:

  1. Найдем подстроку '<'
  2. Начнем захватывать символы в последовательность
    1. Захватим одну или более букву алфавита
  3. Завершим захватывать совпадения
  4. Захватим 0 или более символов, не совпадающих с набором символов '>'
  5. Захватим подстроку '>'
  6. Начнем захватывать символы в последовательность
    1. Начнем захватывать символы в несохраняющую последовательность
      1. Начнем проверку на отсутствие удачного совпадения справа последовательности из
        1. '</'
        2. совпадение найденное на шагах 2-3 (ссылка на последовательность 1)
        3. '>'
      2. Завершим проверку.
      3. Захватим любой символ
    2. Завершим захватывать совпадения.
    3. Произведем захват 0 или более раз
  7. Завершим захватывать совпадения.
  8. Захватим подстроку '</'
  9. Захватим совпадение найденное на шагах 2-3 (ссылка на последовательность 1)
  10. Захватим подстроку '>'

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

  1. <
  2. (
    1. \w+
  3. )
  4. [^>]*
  5. >
  6. (
    1. (?:
      1. (?!
        1. </
        2. \1
        3. >
      2. )
      3. .
    2. )
    3. *
  7. )
  8. </
  9. \1
  10. >

Итак, у нас получилось следующее выражение:

<(\w+)[^>]*>((?:(?!</\1>).)*))</\1>

Оно захватывает любые парные теги вместе с содержимым.

Шаг 3. Выделение требуемых тегов

Используя регулярное выражение, полученное на предыдущем шаге, мы можем выделить из текста сразу несколько типов тегов, используя конструкцию «альтернативная последовательность при отсутствии совпадения слева». В описании используем термин «альтернативная последовательность».

Добавим выделение из текста всего содержимого абзацев и пунктов списка:

  1. Найдем подстроку '<'
  2. Начнем захватывать символы в последовательность
    1. подстроку 'p'
    2. Добавим альтернативную последовательность
    3. подстроку 'li'
  3. Завершим захватывать совпадения
  4. Произведем проверку на удачное совпадение справа набора символов '\s>'
  5. Захватим 0 или более символов, не совпадающих с набором символов '>'
  6. Захватим подстроку '>'
  7. Начнем захватывать символы в последовательность
    1. Начнем захватывать символы в несохраняющую последовательность
      1. Начнем проверку на отсутствие удачного совпадения справа последовательности из
        1. '</'
        2. совпадение найденное на шагах 2-3 (ссылка на последовательность 1)
        3. '>'
      2. Завершим проверку
      3. Захватим любой символ
    2. Завершим захватывать совпадения
    3. Захватим последовательность 0 или более раз
  8. Завершим захватывать совпадения
  9. Захватим подстроку '</'
  10. Захватим совпадение найденное на шагах 2-3 (ссылка на последовательность 1)
  11. Захватим подстроку '>'

Пункты 7 и 8 были добавлены для того, чтобы выражение не захватывало теги, начало которых совпадает с выделяемыми тегами. Например, чтобы при поиске тега <p> не были захвачены теги <param>.

Переводим ее в операторы регулярного выражения:

  1. <
  2. (
    1. p
    2. |
    3. li
  3. )
  4. (?=[\s>])
  5. [^>]*
  6. >
  7. (
    1. (?:
      1. (?!
        1. </
        2. \1
        3. >
      2. )
      3. .
    2. )
    3. *
  8. )
  9. </
  10. \1
  11. >

Новое регулярное выражение:

<(p|li)(?=[\s>])[^>\w]*>((?:(?!</\1>).)*))</\1>

Теперь в тексте будут выделены только теги p и li и все их содержимое.

Шаг 4. Выделение пар имя_атрибута = "значение"

Требования к выражению

  1. справа от имени атрибута должен быть пробел
  2. слева от значения должен быть пробел или закрывающая тег скобка
  3. значение должно быть заключено в одинарные или двойные кавычки
  4. между знаком равенства, именем атрибута и его значением могут быть пробелы

Опишем задачу формальным языком:

  1. Найдем 1 или больше символов \s
  2. Захватим 1 или больше символов \w
  3. Захватим 0 или больше символов \s
  4. Захватим подстроку '='
  5. Захватим 0 или больше символов \s
  6. Начнем захватывать символы в последовательность
    1. Захватим подстроку из набора '»'
  7. Завершим захватывать совпадения.
  8. Захватим 0 или больше символов, не входящих в набор символов, найденный на шагах 6-7 (ссылка на последовательность 1)
  9. Захватим символ, найденный на шагах 6-7 (ссылка на последовательность 1)

Переводим в операторы регулярного выражения:

  1. \s+
  2. \w+
  3. \s*
  4. =
  5. \s*
  6. (
    1. ['»]
  7. )
  8. [^\1]*
  9. \1

Получается следующее регулярное выражение:

\s+\w+\s*=\s*(['"])[^\1]*\1

Модифицируем его, чтобы выражение совпадало только с именем атрибута 'class' и его значением 'content':

\s+class\s*=\s*(['"])content\1

Шаг 5. Добавим в основное выражение проверку на определенные атрибуты

Опишем задачу формальным языком:

  1. Найдем подстроку '<'
  2. Начнем захватывать символы в последовательность
    1. Захватим подстроку 'p'
    2. Добавим альтернативную последовательность
    3. Захватим подстроку 'li'
  3. Завершим захватывать совпадения
  4. Захватим 1 или больше символов \s
  5. Захватим минимальные 0 или больше символов, не совпадающих с набором символов '>'
  6. Добавим регулярное выражение с шага 4: class\s*=\s*(['»])content\1
  7. Захватим 0 или более символов, не совпадающих с набором символов '>'
  8. Захватим подстроку '>'
  9. Начнем захватывать символы в последовательность
    1. Начнем захватывать символы в несохраняющую последовательность
      1. Начнем проверку на отсутствие удачного совпадения справа последовательности из
        1. '</'
        2. совпадение, найденное на шагах 2-3 (ссылка на последовательность 1)
        3. '>'
      2. Завершим проверку
      3. Захватим любой символ
    2. Завершим захватывать совпадения
    3. Захватим последовательность 0 или более раз
  10. Завершим захватывать совпадения
  11. Захватим подстроку '</'
  12. Захватим совпадение, найденное на шагах 2-3 (ссылка на последовательность 1)
  13. Захватим подстроку '>'

Переводим ее в операторы регулярного выражения:

  1. <
  2. (
    1. p
    2. |
    3. li
  3. )
  4. \s+
  5. [^>]*?
  6. class\s*=\s*(['»])content\2
  7. [^>]*
  8. >
  9. (
    1. (?:
      1. (?!
        1. </
        2. \1
        3. >
      2. )
      3. .
    2. )
    3. *
  10. )
  11. </
  12. \1
  13. >

Результирующее выражение:

<(p|li)\s+[^>]*?class\s*=\s*(['"])content\2[^>]*>((?:(?!</\1>).)*)</\1>

Шаг 6. Добавление модификаторов и ограничителей

Ограничители

Практически во всех языках, где имеется поддержка регулярных выражений, возможно выбрать ограничители выражения. Самые распространенные это: / / и # #. В принципе, можно использовать практически любые пары символов, если это поддерживается интерпретатором. При выборе ограничителей лучше исходить из того, какие символы присутствуют в регулярном выражении. Выбирать лучше те, которых в выражении нет. В противном случае придется экранировать эти символы, что сделает выражение более запутанным. В нашем случае стандартные / / не подходят, поскольку они есть внутри регулярного выражения. Поэтому я предлагаю использовать ограничители # #.

Модификаторы

Информацию по всем модификаторам поиска я советую смотреть в специальной справочной литературе, например, в документации по PHP и Perl. Здесь же мы используем i - поиск без учета регистра и s - режим совпадения символа «.» с переводами строк.

Финальное выражение

#<(p|li)\s+[^>]*?class\s*=\s*(['"])content\2[^>]*>((?:(?!</\1>).)*)</\1>#is

Как видите, эта задача решается достаточно просто. При написании статьи я ее выбрал потому, что на форумах очень часто задают вопрос «как выбрать содержимое определенного тега» и «как разобрать HTML разметку». Решение перед вами.

Полезные ссылки

  • Regular-expressions.info - большое количество информации по регам, их реализации в разных языках программирования.
  • Search&Replace for Far - отличный плагин для работы с регами в фаре.
  • RegexBuddy - мощная программа для визуализации регулярных выражений с поддержкой огромного количества диалектов.

Анализ данных, представленных в статье про регулярные выражения в php , подтверждает эффективность применения современных технологий для обеспечения инновационного развития и улучшения качества жизни в различных сферах. Надеюсь, что теперь ты понял что такое регулярные выражения в php , регулярные выражения, поиск с инверсией и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)

создано: 2018-03-04
обновлено: 2021-03-13
132269



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей


avatar
11.5.2020 1:7

Определения специальных символов для регулярных выражений
Цитировать следующий метасимвол
^ Соответствие началу строки
. Соответствует любому символу (кроме новой строки)
$ Соответствует концу строки (или перед новой строкой в ​​конце)
| альтернативность
() Группировка
Класс персонажа
Соответствие 0 или более раз
+ Соответствие 1 или более раз
? Совпадение 1 или 0 раз
n соответствует ровно n раз
n, Соответствовать не менее n раз
n, m Совпадение не менее n, но не более m раз
Больше специальных персонажей
t символ табуляции (HT, TAB)
n перевод строки (LF, NL)
r возврат строки (CR)
f подача формы (FF)
a будильник (звонок) (БЕЛ)
e escape(думаю, troff) (ESC)
033 восьмеричный символ (вспомним PDP-11)
x1B шестнадцатеричный символ
c контрольный символ
l строчный следующий символ (думаю, vi)
u следующий символ в верхнем регистре (думаю, vi)
L строчными до E (думаю, vi)
U прописными до E (думаю, vi)
E конец модификации (думаю, vi)
Q Цитировать (отключить) метасимволы шаблона до E

Еще больше специальных символов
w Соответствует символу «слово (буквенно-цифровой и «_ )
W Соответствует несловесному символу
s Соответствует пробелу
S Соответствует непробельному символу
d Совпадение с цифрой
D Соответствует нецифровому символу
b Соответствует границе слова
B Сопоставить не- (граница слова)
A совпадать только в начале строки
Z Совпадение только в конце строки или до новой строки в конце
z Совпадение только в конце строки
G Соответствует только там, где предыдущий m//g остановлен (работает только с/g)


Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)

Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)