Парсинг полуструктурированных текстовых строк в Python

Нет, такой гарантии нет. Он не определен в соответствии со стандартом C ++.

Bjarne Stroustrup также явно говорит об этом в разделе «Язык программирования C ++», раздел 6.2.2, с некоторыми аргументами:

Better код может быть сгенерирован при отсутствии ограничений на порядок оценки выражения

Хотя это технически относится к более ранней части того же раздела, где говорится, что порядок оценки частей выражения также undefined, т.е.

int x = f(2) + g(3);   // undefined whether f() or g() is called first
1
задан Jan 1 March 2019 в 19:32
поделиться

2 ответа

В зависимости от того, что вы на самом деле хотите от этих строк, вы можете использовать парсер, например, parsimonious:

from parsimonious.nodes import NodeVisitor
from parsimonious.grammar import Grammar

grammar = Grammar(
    r"""
    command     = set operand to? number (operator number)* middle? to? numsys? number
    operand     = (~r"words?" / "speed") ws
    middle      = (~r"[Ww]ords" / "bits")+ ws number
    to          = ws "to" ws
    number      = ws ~r"[-\d.]+" "kts"? ws
    numsys      = ws ("oct" / "hex") ws
    operator    = ws "and" ws
    set         = ~"[Ss]et" ws
    ws          = ~r"\s*"
    """
)

class HorribleStuff(NodeVisitor):
    def __init__(self):
        self.cmds = []

    def generic_visit(self, node, visited_children):
        pass

    def visit_operand(self, node, visited_children):
        self.cmds.append(('operand', node.text))

    def visit_number(self, node, visited_children):
        self.cmds.append(('number', node.text))


examples = ['Set word 45 and 46 to hex 331',
            'set words 45 and 46 bits 3..7 to 280',
            'set word 45 to oct 332',
            'set speed to 60kts Words 3-4 to hex 34']


for example in examples:
    tree = grammar.parse(example)
    hs = HorribleStuff()
    hs.visit(tree)
    print(hs.cmds)

Это даст

[('operand', 'word '), ('number', '45 '), ('number', '46 '), ('number', '331')]
[('operand', 'words '), ('number', '45 '), ('number', '46 '), ('number', '3..7 '), ('number', '280')]
[('operand', 'word '), ('number', '45 '), ('number', '332')]
[('operand', 'speed '), ('number', '60kts '), ('number', '3-4 '), ('number', '34')]
0
ответ дан Jan 1 March 2019 в 19:32
поделиться

Я предлагаю вам разработать программу, которая постепенно исследует синтаксис, который люди использовали для написания сценариев.

Например, каждая инструкция в ваших примерах разбита на часть устройства и часть настроек. Так что вы можете попробовать сопоставить каждую строку с регулярным выражением ^(.+) set (.+). Если вы найдете линии, которые не соответствуют этому шаблону, распечатайте их. Изучите выходные данные, найдите общий шаблон, соответствующий некоторым из них, добавьте соответствующее регулярное выражение в вашу программу (или измените существующее регулярное выражение) и повторите. Продолжайте до тех пор, пока вы не узнаете (в очень общем виде) каждую строку ввода.

(Поскольку заглавные буквы кажутся непоследовательными, вы можете либо выполнять регистронезависимые совпадения, либо конвертировать каждую строку в строчные, прежде чем начинать ее обрабатывать. В более общем случае вы можете найти другие «нормализации», которые упрощают последующую обработку. Например, если люди были непоследовательны в отношении пробелов, вы можете конвертировать каждый пробел символов пробела в один пробел.)

(Если ваш ввод содержит опечатки, например, кто-то написал «ste» для «set», то вы можете изменить регулярное выражение, чтобы учесть это (... (set|ste) ...), или перейдите (копия) во входной файл и просто исправьте опечатку.)

Затем вернитесь к строкам, которые соответствовали ^(.+) set (.+), распечатайте просто первая группа для каждой, и повторите описанный выше процесс только для этих подстрок. Затем повторите процедуру для второй группы в каждой инструкции «set». И так далее, рекурсивно.

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

В зависимости от вашего опыта работы с Python, вы можете найти способы сделать код кратким.

0
ответ дан Michael Dyck 1 March 2019 в 19:32
поделиться
Другие вопросы по тегам:

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