Pyparsing: различия между MatchFirst, Или и oneOf

#pyparsing

#pyparsing

Вопрос:

в Pyparsing, каковы различия между MatchFirst, Or и oneOf

когда в строках есть общие символы, такие как

слово, формулировка, слова

Или([‘слово’, ‘формулировка’, ‘слова’])

MatchFirst([‘слово’, ‘формулировка’, ‘слова’])

oneOf([‘слово’, ‘формулировка’, ‘слова’])

Ответ №1:

Из онлайн-документов (https://pythonhosted.org/pyparsing /)

  • MatchFirst — Если два выражения совпадают, то первое из перечисленных выражений будет совпадать.
  • Or — Если два выражения совпадают, будет использоваться выражение, соответствующее самой длинной строке.
  • oneOf — Помощник для быстрого определения набора альтернативных литералов и гарантирует выполнение самого длительного тестирования при возникновении конфликта, независимо от порядка ввода, но возвращает MatchFirst для лучшей производительности.

MatchFirst проверяет текущее местоположение синтаксического анализа с каждой строкой в ее конструкторе, останавливаясь на первой, которая соответствует.

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

oneOf генерирует Regex or MatchFirst для сопоставления с самым длинным совпадением путем изменения порядка входного списка, когда есть альтернативы с обычными начальными строками, чтобы сначала протестировать более длинную строку.

Ответ №2:

oneOf работает со str строками, разделенными пробелами, и может быть упрощенно определено как

 oneOf = lambda xs: Or(Literal(x) for x in xs.split(" "))
 

While Or работает с ParseElement экземплярами выражений.
Таким образом, вы можете рассматривать либо oneOf как специализацию Or , либо Or как обобщение oneOf .

Вы можете записать oneOf('foo bar') как Literal('foo') ^ Literal('bar') , но вы не можете записать каждое Or выражение с помощью oneOf .

MatchFirst такой же, как Or метод разрешения конфликтов except — Or выдает самое длинное совпадение, а MatchFirst возвращает первое совпадение в порядке определения.

Итак

 expr = Literal('bar') ^ Words(alphanums)
expr.parseString("barstool").asList() == ["barstool"]    
 

но

 expr = Literal('bar') | Words(alphanums)
expr.parseString("barstool").asList() == ["bar"]