Меню

Python совпадение не жадным способом должно быть выполнено

Жадный квантификатор против не жадного.

При повторении регулярного выражения при помощи a* , результирующее действие состоит в том, чтобы захватить как можно больше строки для анализа. Программист «стреляет себе в ногу», когда пытается подобрать таким образом пару сбалансированных разделителей, таких как угловые скобки, окружающие HTML тег. Такой шаблон как ‘ ‘ для сопоставления одного HTML тега не работает из-за жадной природы выражения .* .

Регулярному выражению ‘ ‘ сначала соответствует символ ‘ в теге , а затем выражение .* потребляет всю остальную часть строки до конечного > в , что соответствует последнему совпадению и не совсем то, что требуется. Поэтому механизм регулярных выражений должен отслеживать символ за символом, пока не найдет очередное совпадение для символа > .

В этом случае решение заключается в использовании не жадных квантификаторов *? , +? , ?? , или ? , которые соответствуют как можно меньшему количеству захвата текста для анализа. В приведенном ниже примере символ ‘>’ проверяется сразу после первого совпадения ‘ , и когда это не удается, механизм продвигает символ за раз, повторяя проверку ‘>’ на каждом шаге. Это дает как раз правильный результат:

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

Источник

Python не жадные регулярные выражения

Как мне сделать python регулярное выражение типа «(. *)» Таким, что, учитывая, что «a (b) c (d) e» python соответствует «b» вместо «b» ) CD»?

Я знаю, что могу использовать «[^)]» вместо «.», Но я ищу более общее решение, которое сделает мое регулярное выражение немного чище. Есть ли способ сказать python «эй, сравните это как можно скорее»?

Ты ищешь всесильного «*?»

не жадные квалификаторы * ?, + ?, ?? или ? [. ] сопоставьте как можно меньше текста .

Спецификаторы ‘ * ‘, ‘ + ‘ и ‘ ? ‘ являются жадными; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если RE сопоставлен с

title


. Добавление ‘ ? ‘ после того, как квалификатор заставляет его выполнять сопоставление не жадным или минимальным образом; будет найдено как можно меньше символов. Использование .*? в предыдущем выражении будет совпадать только с

Не будет \\(.*?\\) работать? Это не жадный синтаксис.

Как другие сказали, используя? Модификатор * quantifier решит вашу непосредственную проблему, но будьте осторожны, вы начинаете отклоняться в области, где перестанут работать регулярные выражения, и вместо этого вам нужен анализатор. Например, строка «(foo (bar)) baz» вызовет у вас проблемы.

Использование неадекватного совпадения — хорошее начало, но я бы также посоветовал вам пересмотреть любое использование .* — как насчет этого?

Вы хотите, чтобы это соответствовало «(b)»? Делай, как предложили Цитракс и Паоло. Вы хотите, чтобы это соответствовало «b»? Делать

Источник

Не-жадные регулярные выражения Python

Как сделать регулярное выражение python как » (.* ) «такой, что, учитывая» A (b) c (d) e», python соответствует» b «вместо»b) c (d»?

Я знаю, что могу использовать «[^)]» вместо «.», но я ищу более общее решение, которое помогает регулярное выражение немного чище. Есть ли способ сказать python «Эй, сопоставьте это как можно скорее»?

6 ответов

вы ищете всемогущего’*?’

в ‘ * ‘,’ + ‘ и ‘ ? ‘ квалификаторы все жадные; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если RE сравнивается с ‘

title


‘. Добавление’ ? ‘ после того, как квалификатор заставляет его выполнять матч не жадным или минимальным способом; как можно меньше символов будет сопоставлено. С помощью .*? в предыдущем выражении будет соответствовать только’

не будет \(.*?\) работы? Это не-жадный синтаксис.

как другие сказали, используя ? модификатор на * quantifier решит вашу непосредственную проблему, но будьте осторожны, вы начинаете блуждать в областях, где регексы перестают работать, и вам нужен парсер вместо этого. Например, строка «(foo (bar)) baz» вызовет у вас проблемы.

вы хотите, чтобы он соответствовал «(b)»? Делай, как Zitrax и Паоло предложил. Вы хотите, чтобы он соответствовал «б»? Do

использование ungreedy match-хорошее начало, но я также предлагаю вам пересмотреть любое использование .* — Как насчет этого?

Источник

Примеры применения регулярных выражений в Python

Регулярные выражения, также называемые regex, синтаксис или, скорее, язык для поиска, извлечения и работы с определенными текстовыми шаблонами большего текста. Он широко используется в проектах, которые включают проверку текста, NLP (Обработка естественного языка) и интеллектуальную обработку текста.

Введение в регулярные выражения

Регулярные выражения, также называемые regex, используются практически во всех языках программирования. В python они реализованы в стандартном модуле re .
Он широко используется в естественной обработке языка, веб-приложениях, требующих проверки ввода текста (например, адреса электронной почты) и почти во всех проектах в области анализа данных, которые включают в себя интеллектуальную обработку текста.

Эта статья разделена на 2 части.

Прежде чем перейти к синтаксису регулярных выражений, для начала вам лучше понять, как работает модуль re .

Итак, сначала вы познакомитесь с 5 основными функциями модуля re , а затем посмотрите, как создавать регулярные выражения в python.
Узнаете, как построить практически любой текстовый шаблон, который вам, скорее всего, понадобится при работе над проектами, связанными с поиском текста.

Что такое шаблон регулярного выражения и как его скомпилировать?

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

Основным примером является \s+ .
Здесь \ s соответствует любому символу пробела. Добавив в конце оператор + , шаблон будет иметь не менее 1 или более пробелов. Этот шаблон будет соответствовать даже символам tab \t .

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

Вышеупомянутый код импортирует модуль re и компилирует шаблон регулярного выражения, который соответствует хотя бы одному или нескольким символам пробела.

Как разбить строку, разделенную регулярным выражением?

Рассмотрим следующий фрагмент текста.

У меня есть три курса в формате “[Номер курса] [Код курса] [Название курса]”. Интервал между словами разный.

Передо мной стоит задача разбить эти три предмета курса на отдельные единицы чисел и слов. Как это сделать?
Их можно разбить двумя способами:

  • Используя метод re.split .
  • Вызвав метод split для объекта regex .

Оба эти метода работают. Но какой же следует использовать на практике?
Если вы намерены использовать определенный шаблон несколько раз, вам лучше скомпилировать регулярное выражение, а не использовать re.split множество раз.

Поиск совпадений с использованием findall, search и match

Предположим, вы хотите извлечь все номера курсов, то есть 100, 213 и 156 из приведенного выше текста. Как это сделать?

Что делает re.findall()?

В приведенном выше коде специальный символ \ d является регулярным выражением, которое соответствует любой цифре. В этой статье вы узнаете больше о таких шаблонах.
Добавление к нему символа + означает наличие по крайней мере 1 числа.

Подобно + , есть символ * , для которого требуется 0 или более чисел. Это делает наличие цифры не обязательным, чтобы получилось совпадение. Подробнее об этом позже.

В итоге, метод findall извлекает все вхождения 1 или более номеров из текста и возвращает их в список.

re.search() против re.match()

Как понятно из названия, regex.search() ищет шаблоны в заданном тексте.
Но, в отличие от findall , который возвращает согласованные части текста в виде списка, regex.search() возвращает конкретный объект соответствия. Он содержит первый и последний индекс первого соответствия шаблону.

Аналогично, regex.match() также возвращает объект соответствия. Но разница в том, что он требует, чтобы шаблон находился в начале самого текста.

В качестве альтернативы вы можете получить тот же результат, используя метод group() для объекта соответствия.

Как заменить один текст на другой, используя регулярные выражения?

Для изменения текста, используйте regex.sub() .
Рассмотрим следующую измененную версию текста курсов. Здесь добавлена табуляция после каждого кода курса.

Из вышеприведенного текста я хочу удалить все лишние пробелы и записать все слова в одну строку.

Для этого нужно просто использовать regex.sub для замены шаблона \s+ на один пробел .

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

Это можно сделать, используя отрицательное соответствие (?!\n) . Шаблон проверяет наличие символа новой строки, в python это \n , и пропускает его.

Группы регулярных выражений

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

Предположим, что я хочу извлечь номер курса, код и имя как отдельные элементы. Не имея групп мне придется написать что-то вроде этого.

Давайте посмотрим, что получилось.
Я скомпилировал 3 отдельных регулярных выражения по одному для соответствия номерам курса, коду и названию.
Для номера курса, шаблон 5+ указывает на соответствие всем числам от 0 до 9. Добавление символа + в конце заставляет найти по крайней мере 1 соответствие цифрам 0-9. Если вы уверены, что номер курса, будет иметь ровно 3 цифры, шаблон мог бы быть 6 <3>.

Для кода курса, как вы могли догадаться, [А-ЯЁ] <3>будет совпадать с 3 большими буквами алфавита А-Я подряд (буква “ё” не включена в общий диапазон букв).

Для названий курса, [а-яА-ЯёЁ] <4,>будем искать а-я верхнего и нижнего регистра, предполагая, что имена всех курсов будут иметь как минимум 4 символа.

Можете ли вы догадаться, каков будет шаблон, если максимальный предел символов в названии курса, скажем, 20?
Теперь мне нужно написать 3 отдельные строки, чтобы разделить предметы. Но есть лучший способ. Группы регулярных выражений.
Поскольку все записи имеют один и тот же шаблон, вы можете создать единый шаблон для всех записей курса и внести данные, которые хотите извлечь из пары скобок ().

Обратите внимание на шаблон номера курса: 4+ , код: [А-ЯЁ] <3>и название: [а-яА-ЯёЁ] <4,>они все помещены в круглую скобку (), для формирования группы.

Что такое “жадное” соответствие в регулярных выражениях?

По умолчанию, регулярные выражения должны быть жадными. Это означает, что они пытаются извлечь как можно больше, пока соответствуют шаблону, даже если требуется меньше.

Давайте рассмотрим пример фрагмента HTML, где нам необходимо получить тэг HTML.

Вместо совпадения до первого появления ‘>’, которое, должно было произойти в конце первого тэга тела, он извлек всю строку. Это по умолчанию “жадное” соответствие, присущее регулярным выражениям.

С другой стороны, ленивое соответствие “берет как можно меньше”. Это можно задать добавлением ? в конец шаблона.

Если вы хотите получить только первое совпадение, используйте вместо этого метод поиска search .

Наиболее распространенный синтаксис и шаблоны регулярных выражений

Теперь, когда вы знаете как пользоваться модулем re, давайте рассмотрим некоторые обычно используемые шаблоны подстановок.

Основной синтаксис

. Один символ кроме новой строки
\. Просто точка . , обратный слеш \ убирает магию всех специальных символов.
\d Одна цифра
\D Один символ кроме цифры
\w Один буквенный символ, включая цифры
\W Один символ кроме буквы и цифры
\s Один пробельный (включая таб и перенос строки)
\S Один не пробельный символ
\b Границы слова
\n Новая строка
\t Табуляция

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

$ Конец строки
^ Начало строки
ab|cd Соответствует ab или de.
[ab-d] Один символ: a, b, c, d
[^ab-d] Любой символ, кроме: a, b, c, d
() Извлечение элементов в скобках
(a(bc)) Извлечение элементов в скобках второго уровня

Повторы

[ab]

2 непрерывных появления a или b
[ab]

от 2 до 5 непрерывных появления a или b
[ab]

2 и больше непрерывных появления a или b
+ одно или больше
* 0 или больше
? 0 или 1

Примеры регулярных выражений

Любой символ кроме новой строки

Точки в строке

Любая цифра

Все, кроме цифры

Любая буква или цифра

Все, кроме букв и цифр

Только буквы

Соответствие заданное количество раз

1 и более вхождений

Любое количество вхождений (0 или более раз)

0 или 1 вхождение

Граница слова
Границы слов \b обычно используются для обнаружения и сопоставления началу или концу слова. То есть, одна сторона является символом слова, а другая сторона является пробелом и наоборот.

Например, регулярное выражение \btoy совпадает с ‘toy’ в ‘toy cat’, но не в ‘tolstoy’. Для того, чтобы ‘toy’ соответствовало ‘tolstoy’, используйте toy\b .
Можете ли вы придумать регулярное выражение, которое будет соответствовать только первой ‘toy’в ‘play toy broke toys’? (подсказка: \ b с обеих сторон)
Аналогично, \ B будет соответствовать любому non-boundary( без границ).
Например, \ Btoy \ B будет соответствовать ‘toy’, окруженной словами с обеих сторон, как в ‘antoynet’.

Практические упражнения

Давайте немного попрактикуемся. Пришло время открыть вашу консоль. (Варианты ответов здесь)

1. Извлеките никнейм пользователя, имя домена и суффикс из данных email адресов.

2. Извлеките все слова, начинающиеся с ‘b’ или ‘B’ из данного текста.

3. Уберите все символы пунктуации из предложения

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

  1. Извлеките все текстовые фрагменты между тегами с HTML страницы: https://raw.githubusercontent.com/selva86/datasets/master/sample.html
    Код для извлечения HTML страницы:

Ответы

\b находится слева от ‘B’, значит слово должно начинаться на ‘B’.
Добавьте flags=re.IGNORECASE , что бы шаблон был не чувствительным к регистру.

Надеемся, информация была вам полезна. Стояла цель — познакомить вас с примерами регулярных выражений легким и доступным для запоминания способом.

Источник

Читайте также:  Способы как носить шарф хомут
Adblock
detector