Pyparsing — буквальный текст с разрывами строк в разных местах

Я использую pyparsing для анализа документов, содержащих текст, в котором концы строк различаются по местоположению. Мне нужно написать выражение синтаксического анализатора, которое соответствует тексту независимо от места разрыва строки. НЕ работает следующее:

from __future__ import print_function
from pyparsing import *

string_1 = """The quick brown 
fox jumps over the lazy dog.
"""

string_2 = """The quick brown fox jumps
over the lazy dog.
"""

my_expr = Literal(string_1)
print(my_expr.searchString(string_1)
print(my_expr.searchString(string_2)

В результате на консоли отображается следующее:

[['The quick brown \nfox jumps over the lazy dog.\n']]
[]

Поскольку разрывы строк включены в ParserElement.DEFAULT_WHITE_CHARS, я не понимаю, почему обе строки не соответствуют моему выражению. Как создать элемент синтаксического анализатора, который СООТВЕТСТВУЕТ тексту независимо от того, где происходит разрыв строки?


person Dave    schedule 18.11.2011    source источник


Ответы (1)


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

Вы можете пропустить пробелы, разбив строку на отдельные литералы (добавление строки к выражению pyparsing автоматически создает литерал из этой строки):

from pyparsing import *

my_expr = Literal("The") + "quick" + "brown" + "fox" + "jumps" + "over" + "the" + "lazy" + "dog"

string_1 = """The quick brown 
fox jumps over the lazy dog.
"""

string_2 = """The quick brown fox jumps
over the lazy dog.
"""

for test in (string_1, string_2):
    print '-'*40
    print test
    print my_expr.parseString(test)
    print

Если вам не нравится вводить все эти отдельные строки в кавычках, вы можете сделать, чтобы Python разделил строку для вас, сопоставил их с литералами и передал весь список, чтобы составить pyparsing И:

my_expr = And(map(Literal, "The quick brown fox jumps over the lazy dog".split()))

Если вы хотите сохранить исходный пробел, оберните выражение в originalTextFor:

my_expr = originalTextFor(my_expr)
person PaulMcG    schedule 19.11.2011
comment
Спасибо, Павел, это очень полезно. Я буду использовать подход карты. - person Dave; 21.11.2011