Подтвердить что ты не робот

Perl Compatible Regular Expression (PCRE) в Python

Мне нужно разобрать некоторые строки на основе PCRE в Python, и я не знаю, как это сделать.

Строки, которые я хочу разборки, выглядят следующим образом:

match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s p/MySQL/ i/$1/

В этом примере мне нужно получить разные элементы:

"m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s" ; "p/MySQL/" ; "i/$1/"

Единственное, что я нашел в отношении манипуляции с PCRE в Python, это этот модуль: http://pydoc.org/2.2.3/pcre.html (но он написал это .so..)

Знаете ли вы, существует ли какой-нибудь модуль python для синтаксического анализа такого рода строк?

4b9b3361

Ответ 1

Будьте особенно осторожны с не-ASCII в Python

Есть некоторые очень тонкие проблемы с тем, как Python занимается или не справляется с не-ASCII в шаблонах и строках. Хуже того, эти различия существенно различаются не только по той версии Python, которую вы используете, но и по тому, есть ли у вас "широкая сборка".

В общем, когда вы делаете Unicode, Python3 с широким построением лучше всего работает, а Python2 с узкой сборкой работает хуже, но все комбинации все еще довольно далеки от того, как работают регулярные выражения Perl по отношению к Unicode. Если вы ищете шаблоны ᴘᴄʀᴇ в Python, вам, возможно, придется искать немного дальше, чем его старый модуль re.

РЕДАКТИРОВАТЬ: досадные "широкомасштабные" проблемы имеют окончательно исправлены раз и навсегда - если вы используете достаточно продвинутый выпуск Python. Вот выдержка из примечаний к выпуску v3.3:

Функции

Изменения, внесенные PEP 393, следующие:

  • Python теперь всегда поддерживает полный диапазон кодовых точек Unicode, включая не BMP (т.е. от U + 0000 до U + 10FFFF). Различие между узкими и широкими сборками больше не существует, и теперь Python ведет себя как широкая сборка, даже под Windows.
  • Со смертью узких сборок также были устранены проблемы, характерные для узких сборок, например:
    • len() теперь всегда возвращает 1 для символов без BMP, поэтому len('\U0010FFFF') == 1;
    • суррогатные пары не рекомбинируются в строковых литералах, поэтому '\uDBFF\uDFFF' != '\U0010FFFF';
    • индексирование или резка не BMP-символов возвращает ожидаемое значение, поэтому '\U0010FFFF'[0] теперь возвращает '\U0010FFFF', а не '\uDBFF';
    • все остальные функции в стандартной библиотеке теперь корректно обрабатывают не-BMP-коды.
  • Значение sys.maxunicode теперь всегда 1114111 (0x10FFFF в шестнадцатеричном формате). Функция PyUnicode_GetMax() по-прежнему возвращает 0xFFFF или 0x10FFFF для обратной совместимости и не должна использоваться с новым Unicode API (см. issue 13054).
  • The ./configure флаг --with-wide-unicode удален.

Будущее Python Regexes

В отличие от того, что доступно в стандартной библиотеке дистрибутивов Python re, модуль Matthew Barnetts regex для Python 2 и Python 3 аналогичен, намного лучше, в любом случае, и, скорее всего, заменит re в конечном итоге. Его особая значимость в вашем вопросе заключается в том, что его библиотека regex намного больше ᴘᴄʀᴇ (т.е. гораздо больше Perl-совместимой) во всех отношениях, чем re, которая будет делать портирование Perl-регулярных выражений Python вам легче. Потому что это перезапись (как в случае с царапинами, а не в гамбургере:), она была написана с учетом не-ASCII, что re не было.

Таким образом, библиотека regex гораздо ближе соответствует рекомендациям UTS # 18: Unicode Regular Expressions в том, как она приближается к вещам. Он соответствует или превосходит требования UTS № 18 уровня 1 в большинстве случаев, если не во всех отношениях, то, что вам обычно нужно использовать библиотеку регулярных выражений ICU или самому Perl для - или если вы особенно мужественны, новая Java 7 для своих регулярных выражений, поскольку это также соответствует требованиям уровня 1 от UTS # 18.

Помимо требований уровня 1, которые абсолютно необходимы для базовой поддержки Unicode, но которые не удовлетворяются текущей библиотекой re Pythons,, библиотека awesome regex также соответствует уровню второго уровня требования для RL2.5 Именованные символы (\N{...})), RL2.2 Расширенные кластеры Grapheme (\X) и новый RL2.7 на Full Properties из версии 14 UTS # 18.

Модуль Matthews regex также выполняет разметку Unicode, так что нечувствительные к регистру совпадения работают над Unicode, , который re не поддерживает.

РЕДАКТИРОВАТЬ: это уже не так, потому что regex теперь поддерживает полный Unicode casefolding, например Perl и Ruby.

Одно супер-крошечное различие заключается в том, что на данный момент шаблоны без учета регистра в Perls используют полные строковые ориентированные фреймы, в то время как его модуль regex по-прежнему использует простые одномерные char -ориентированные фреймы, но это то, глядя в. На самом деле это очень сложная проблема, одна из которых помимо Perl, только Ruby даже пытается.

В случае полной casefolding это означает, что (например) "ß" теперь правильные совпадения "SS", "SS", "ſſ", "ſs" (и т.д.), если выбрано совпадение по регистру. (Это, по общему признанию, более важно в греческом script, чем в латинском.)

См. также слайды или исходный код документа из моих 3-х разговоров OSCON2011 под названием " Поддержка Unicode Shootout: The Good, the Bad и (в основном) Ugly" для общих проблем в поддержке Unicode в Javascripts, PHP, Go, Ruby, Python, Java и Perl. Если вы не можете использовать регулярные выражения Perl или, возможно, библиотеку регулярных выражений ICU (у которых нет названий захватов, увы!), То Matthews regex для Python, вероятно, ваш лучший снимок.


Nᴏᴛᴀ Bᴇɴᴇ s.ᴠ.ᴘ. (= sil vous plaît, et même sil ne vous plaît pas:) Следующая незатребованная некоммерческая непроизнесенность фактически не была написана автором библиотеки Python regex.:)

Прохладный regex Особенности

Библиотека Python regex имеет cornucopeia функций superneat, некоторые из которых не найдены ни в одной другой системе regex. Это очень важно проверить независимо от того, используете ли вы его для своей ᴘᴄʀᴇ-ness или ее звездной поддержки Unicode.

Некоторые из этих модулей представляют интерес:

  • Variable-width lookbehind, функция, которая довольно редка в двигателях регулярных выражений и очень расстраивает, чтобы не иметь, когда вы действительно этого хотите. Это может быть наиболее часто запрашиваемая функция в регулярных выражениях.
  • Обратный поиск, поэтому вам не нужно сначала отменить свою строку.
  • Скопированные параметры ismx -type, так что (?i:foo) только casefolds для foo, а не в целом, или (?-i:foo), чтобы отключить его только на foo. Так Perl работает (или может).
  • Нечеткое совпадение на основе расстояния редактирования (которое также имеет Udi Manbers agrep и glimpse)
  • Неявные кратчайшие по длине отсортированные списки имен с помощью \L<list> интерполяции
  • Метасимволы, которые специально соответствуют только началу или только концу слова, а не любой из сторон (\m, \m)
  • Поддержка всех разделителей строк Юникода (Java может это сделать, как и Perl, хотя и несколько неохотно с \R за RL1.6.
  • Операции с полным набором операций - объединение, пересечение, разность и симметричная разность - по классам с символами в скобках на RL1.3, что намного проще, чем попасть на него в Perl,
  • Позволяет повторять группы захвата, такие как (\w+\s+)+, где вы можете получить все отдельные совпадения первой группы, а не только ее последнее совпадение. (Я считаю, C♯ тоже может это сделать.)
  • Более прямой способ получить совпадение совпадений, чем скрытые группы захвата в виде.
  • Начальные и конечные позиции для всех групп для последующих операций нарезки/подстроки, как Perls @+ и @- массивы.
  • Оператор ветки reset с помощью (?|...|...|...|) до reset, нумерация групп в каждой ветки, как это работает в Perl.
  • Может быть настроен на то, чтобы ваш кофе ждал вас утром.
  • Поддержка более сложных границ слов из RL2.3.
  • Предполагает строки Unicode по умолчанию и полностью поддерживает RL1.2a, чтобы \w, \b, \s и такая работа в Юникоде.
  • Поддерживает \X для графем.
  • Поддерживает утверждение точки продолжения \G.
  • Правильно работает для 64-битных построений (re имеет только 32-разрядные индексы).
  • Поддержка многопоточности.

Хорошо, хватит шумихи.:)

Еще один тонкий альтернативный двигатель регулярных выражений

Последней альтернативой, заслуживающей внимания, если вы являетесь разработчиком regex, является привязка Python-библиотек к Russ Coxs awesome Библиотека RE2, Он также поддерживает Unicode изначально, в том числе простой char основанный casefolding, и в отличие от re он, в частности, обеспечивает как свойства Unicode General Category, так и Unicode script, которые являются двумя ключевыми свойствами, которые наиболее часто необходимы для более простые виды обработки Юникода.

Хотя RE2 пропускает несколько функций Unicode, таких как \N{...} поддержка символов с символами, найденная в ICU, Perl и Python, имеет чрезвычайно серьезные вычислительные преимущества, которые делают его предпочтительным движком выбора каждый раз вы беспокоитесь о атаках типа "отказ в обслуживании", связанных с голодом, с помощью регулярных выражений в веб-запросах и т.д. Он управляет этим, запрещая обратные ссылки, которые заставляют регулярное выражение перестать быть регулярным и подвергать риску суперэкспоненциальные взрывы во времени и пространстве.

Связи библиотек для RE2 доступны не только для C/С++ и Python, но также для Perl и, в особенности, для Go, где в скором времени будет заменена стандартная библиотека регулярных выражений.

Ответ 2

Вы ищете '(\w/[^/]+/\w*)'.

Используется так,

import re
x = re.compile('(\w/[^/]+/\w*)')
s = 'match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s p/MySQL/ i/$1/'
y = x.findall(s)
# y = ['m/^.\x00\x00\x00\n(4\\.[-.\\w]+)\x00...\x00/s', 'p/MySQL/', 'i/$1/']

Нашел его, играя с Эди Вейцем Regex Coach, поэтому благодаря комментариям к вопросу, который заставил меня вспомнить его существование.