Pyparsing - буквальный текст с разрывами строк в разных местах - PullRequest
2 голосов
/ 18 ноября 2011

Я использую 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, я не понимаю, почему обе строки не соответствуют моему выражению. Как создать элемент синтаксического анализа, который соответствует тексту независимо от того, где происходят разрывы строк?

1 Ответ

2 голосов
/ 19 ноября 2011

Ваш вопрос является хорошим примером того, почему я не рекомендую людям определять литералы со встроенным пробелом, потому что это побеждает встроенный пропуск в 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 разбил строку для вас, сопоставил их с литералами и скормил весь список, чтобы составить двойное выражение И:

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

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

my_expr = originalTextFor(my_expr)
...