Обнаруживать, принимает ли регулярное выражение подмножество другого регулярного выражения или нет? [dубликат]

Иногда вам нужно удалить последовательные пробелы. Вы можете сделать это следующим образом:

  $ str = «Мое имя»;  $ str = preg_replace ('/ \ s \ s + /', '', $ str);   

Выход:

  Меня зовут  
14
задан feeling unwelcome 15 June 2011 в 21:16
поделиться

6 ответов

Я думаю, мдд; в теории; чтобы определить, соответствует ли regexp A подмножество того, что соответствует регулярному выражению B , алгоритм:

  1. Вычислить минимальный детерминированный конечный автомат B , а также «объединения» A | B .
  2. Проверьте, идентичны ли два DFA. Это верно тогда и только тогда, когда A соответствует подмножеству того, что соответствует B.

Однако, вероятно, это был бы крупный проект, чтобы сделать это на практике. Существуют такие пояснения, как Построение DFA минимального состояния из регулярного выражения , но они имеют тенденцию рассматривать математически чистые регулярные выражения. Вам также придется обрабатывать расширения, которые Python добавляет для удобства. Более того, если какое-либо из расширений заставляет язык быть нерегулярным (я не уверен, что это так), вы можете не справиться с этими.

Но что вы пытаетесь сделать ? Возможно, есть более простой подход ...?

11
ответ дан reinierpost 15 August 2018 в 23:16
поделиться
  pip3 установить https://github.com/leafstorm/lexington/archive/master.zip python3 & gt; & gt; & gt; & gt;  из lexington.regex import Regex как R & gt; & gt; & gt; & gt;  из значения lexington.regex Null & gt; & gt; & gt; & gt; & gt;  из сокращения импорта functools & gt; & gt; & gt; & gt; & gt; & gt;  из строки import ascii_lowercase, цифры & gt; & gt; & gt; & gt; & gt;  a_z = уменьшить (lambda a, b: a | R (b), ascii_lowercase, Null) & gt; & gt; & gt; & gt; & gt; & gt;  b_x = уменьшить (lambda a, b: a | R (b), ascii_lowercase [1: -2], Null) & gt; & gt; & gt; & gt;  a_z |  b_x == a_z Истина & gt; & gt; & gt; & gt; & gt; & gt; & gt;  m_n = R ("m") |  R ("n") & gt; & gt; & gt; & gt; & gt;  zero_nine = уменьшить (lambda a, b: a | R (b), цифры, Null) & gt; & gt; & gt; & gt;  m_n |  zero_nine == m_n False  

Также успешно протестирован с Python 2. См. также , как это сделать с другой библиотекой .

Альтернативно, pip3 установите https://github.com/ferno/greenery/archive/master.zip и:

  из greenery.lego import parse как p a_z = p (  "[az]") b_x = p ("[bx]") утверждают a_z |  b_x == a_z m_n = p ("m | n") zero_nine = p ("[0-9]") утверждать не m_n |  zero_nine == m_n  
6
ответ дан Community 15 August 2018 в 23:16
поделиться
  • 1
    Разрешение обратных ссылок, вероятно, делает указанную проблему неразрешимой, но у меня нет доказательств этого. – reinierpost 20 August 2013 в 13:17

Требуется некоторое уточнение:

.

  rA = re.compile ('(? & lt ;!) [a-z52] +')   

'(? & lt ;!) [a-z52] +' является паттерном

rA является экземпляром класса RegexObject , тип которого & lt; * type '_sre.SRE_Pattern'> *.

Лично я использую термин regex исключительно для этого типа объектов, а не для шаблона.

Обратите внимание, что rB = re.compile (rA) также возможно, он создает один и тот же объект (id (rA) == id (rB) равен True)


  ch = 'lshdgbfcs luyt52uir bqisuytfqr454' x = rA.match (ch) # или y = rA.search (ch)  

x и y являются экземплярами класса MatchObject , тип которого - * & lt; type '_sre.SRE_Match'> *


.

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

Я не думаю, что такой способ существует, независимо от теоретического или практически.

0
ответ дан eyquem 15 August 2018 в 23:16
поделиться
  • 1
    Если вы ограничиваете себя действительными математическими регулярными выражениями, это работает в теории и на практике! Смотрите мой ответ! – Janus Troelsen 31 August 2015 в 22:53

Вы должны сделать что-то в этом направлении:

  re.match ("\ [[bx] - [bx] \]", "[az]")  [  ! d4] 

Регулярное выражение должно определить, как должна выглядеть строка. Если вы хотите сопоставить открытую квадратную скобку, за которой следует буква от b до x, тогда тире, затем другая буква от b до x и, наконец, закрывающая квадратная скобка, решение выше должно работать.

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

1
ответ дан Francois Deschenes 15 August 2018 в 23:16
поделиться
  • 1
    Соответствие строк фактического выражения слишком хаки (каждое выражение требует ручной работы), я бы предпочел использовать библиотеку, которая реализует реальные регулярные выражения, как в моем ответе. – Janus Troelsen 31 August 2015 в 22:51

Это возможно при строчном представлении регулярного выражения, так как любая строка может быть сопоставлена ​​с регулярными выражениями, но не с скомпилированной версией, возвращаемой re.compile . Однако я не понимаю, какое использование это будет.

Edit: похоже, вы ищете возможность определить, является ли язык , определенный RE , подмножеством других RE. Да, я думаю, что это возможно, но нет, модуль Python re не делает этого.

1
ответ дан Fred Foo 15 August 2018 в 23:16
поделиться
  • 1
    Я думаю, что идея OP для этого здесь - это «равноправие шаблона», хотя из приведенного примера то, что OP считает True , не является истинным равенством, так как второй шаблон соответствует подмножеству первого. – AJ. 15 June 2011 в 20:58

Проверка сообщения «antinome» с использованием двух регулярных выражений: 55 * и 5 *:

REGEX_A: 55 * [Это соответствует «5», «55», «555» и т. д. и делает НЕ соответствует «4», «54» и т. Д.]

REGEX_B: 5 * [Это соответствует «", "5" "55", "555" и т. Д. И не соответствует "4", "54 "и т. д.]

[Здесь мы предположили, что 55 * неявно. 55 . * и 5 * нет. 5 . * - Вот почему 5 * не соответствует 4]

REGEX_A может иметь NFA, как показано ниже:

  {A} - 5 - & gt; {B} -  epsilon - & gt; {C} - 5 - & gt; {D} - epsilon - & gt; {E} {B} ----------------- epsilon -  ------- & GT;  {E} {C} & lt; --- epsilon ------ {E}  

REGEX_B может иметь NFA, как показано ниже:

   {A} - epsilon - & gt; {B} - 5 - & gt; {C} - epsilon - & gt; {D} {A} --------------  epsilon ----------- & gt;  {D} {B} & lt; --- epsilon ------ {D}  

Теперь мы можем получить NFA * DFA (REGEX_A | REGEX_B), как показано ниже:

  NFA: {состояние A} --- epsilon - & gt;  {состояние B} --- 5 - & gt;  {state C} --- 5 - & gt;  {состояние D} {состояние C} --- epsilon - & gt;  {состояние D} {состояние C} & lt; --- epsilon - {состояние D} {состояние A} --- epsilon - & gt;  {state E} --- 5 - & gt;  {состояние F} {состояние E} --- epsilon - & gt;  {состояние F} {состояние E} & lt; --- epsilon - {состояние F} NFA - & gt;  DFA: |  5 |  epsilon * ---- + -------------- + -------- A |  B, C, E, F, G |  A, C, E, F B |  C, D, E, F |  B, C, E, F c |  C, D, E, F |  C D |  C, D, E, F, G |  C, D, E, F E |  C, D, E, F, G |  C, E, F F |  C, E, F, G |  F G |  C, D, E, G |  C, E, F, G 5 (epsilon *) ------------- + --------------------- A |  B, C, E, F, G B, C, E, F, G |  C, D, E, F, G C, D, E, F, G |  C, D, E, F, G Наконец, DFA для (REGEX_A | REGEX_B): {A} - 5 --- & gt; {B, C, E, F, G} - 5 --- & gt;  {C, D, E, F, G} {C, D, E, F, G} --- 5 - & gt;  {C, D, E, F, G} Примечание: {A} является начальным состоянием и {C, D, E, F, G} принимает состояние.   

Аналогично DFA для REGEX_A (55 *):

  |  5 |  epsilon * ---- + -------- + -------- A |  B, C, E |  A B |  C, D, E |  B, C, E C |  C, D, E |  C D |  C, D, E |  C, D, E E |  C, D, E |  C, E 5 (epsilon *) ------- + --------------------- A |  B, C, E B, C, E |  C, D, E C, D, E |  C, D, E {A} ---- 5 ----- & gt;  {B, C, E} - 5 --- {C, D, E} {C, D, E} - 5 --- & gt; {C, D, E} Примечание: {A} является  (C, D, E) принимает состояние  

Аналогично DFA для REGEX_B (5 *):

  |  5 |  epsilon * ---- + -------- + -------- A |  B, C, D |  A, B, D B |  B, C, D |  B C |  B, C, D |  B, C, D D |  B, C, D |  B, D 5 (epsilon *) ------- + --------------------- A |  B, C, D B, C, D |  B, C, D {A} ---- 5 ----- & gt;  {B, C, D} {B, C, D} --- 5 --- & gt;  {B, C, D} Примечание: {A} является начальным состоянием и {B, C, D} принимает состояние  

Выводы:

  DFA  REGX_A | REGX_B, идентичный DFA REGX_A, подразумевает, что REGEX_A является подмножеством REGEX_B DFA REGX_A | REGX_B НЕ идентичен DFA REGX_B - не может выводиться ни о каких gerexes.   
6
ответ дан JakeGould 15 August 2018 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: