Разбиение строки на части (с помощью регулярных выражений?) - PullRequest
0 голосов
/ 13 декабря 2018

Вопрос, возникающий из https://stackoverflow.com/a/53750697/856090 ответа.

Мы получаем "входную" строку.

Входная строка разбивается на несколько "команд" по + сэто на \s+\+\s+ регулярное выражение.Однако при разбиении кавычки + (\+) должны игнорироваться.

Каждая команда затем разделяется на несколько «аргументов» пробельными символами, но кавычки (\) пробела не учитываются при разбиении ивместо этого становится частью аргумента.

Цитируется \ (то есть \\) становится обычным символом \ и сам не участвует в цитировании.

Мое решение заключается в обработкестрока ввода char-by-char со специальным поведением для \, + и пробельных символов.Это медленно и не элегантно.Я прошу альтернативное решение (например, с помощью регулярных выражений).

Я пишу на Python 3.


Например,

filter1 + \
chain -t http://www.w3.org/1999/xhtml -n error + \
transformation filter2 --arg x=y

преобразование filter3

становится

[['filter1'],
 ['chain', '-t', 'http://www.w3.org/1999/xhtml', '-n', 'error'],
 ['transformation', 'filter2', '--arg', 'x=y']]

и

a \+ b + c\ d

становится

 [['a', '+', 'b'], ['c d']]

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Я написал свою собственную версию процедуры:

import re


def split_pipeline(s):
    res = [['']]
    r = r'\\\\|\\\+|\\\s|\s+\+\s+|\s+|[^\s\\]+'
    for m in re.finditer(r, s, re.M|re.S):
        if m[0][0] == '\\':
            res[-1][-1] += m[0][1:]
        elif re.match(r'^\s+\+\s+$', m[0], re.M|re.S):
            res.append([''])
        elif re.match(r'^\s+$', m[0], re.M | re.S):
            res[-1].append('')
        else:
            res[-1][-1] += m[0]
    return res

print(split_pipeline(r'a\\ \+  b + c\ d'))
# [['a\\', '+', 'b'], ['c d']]
0 голосов
/ 13 декабря 2018

Вот ответ вашей проблемы.

Здесь функция get_splitted_strings_for () принимает 1 параметр типа string s , разбивает 1 на 1, 2 раза и, наконец, сохраняет результат в 2dсписок.

import re

def get_splitted_strings_for(s): 
    splits = []
    splits1 = re.split(r"\s*\+\s+\\\s*|\s+\+\s+", s)

    for split in splits1: 
        if "\+" in split: 
            split = split.replace("\\",  "") 
            splits.append(split.split()) 
        elif "\\" in split: 
            splits.append([split.replace("\\", "")]) 
        else: 
            arr = re.split(r"\s+", split.replace("\\", '')) 
            splits.append(arr) 

    return splits

s = "filter1 + \ chain -t http://www.w3.org/1999/xhtml -n error + \ transformation filter2 --arg x=y"
print(get_splitted_strings_for(s))

# [['filter1'], ['chain', '-t', 'http://www.w3.org/1999/xhtml', '-n', 'error'], ['transformation', 'filter2', '--arg', 'x=y']]

print()  # New line

s2 = "a \+ b + c\ d"
print(get_splitted_strings_for(s2))
# [['a', '+', 'b'], ['c d']]
...