Как использовать разделительные строки с закрытыми скобками в качестве разделителя - PullRequest
0 голосов
/ 05 апреля 2020

Если у меня есть грязная строка типа '[Carrots] [Broccoli] (cucumber)-(tomato) irrelevant [spinach]', и я хочу разбить ее на список, чтобы каждая часть в любой скобке представляла собой элемент типа ['Carrots', 'Broccoli', 'cucumber', 'tomato', 'spinach'] Как бы я это сделал? Я не могу найти способ заставить метод .split() работать.

Ответы [ 3 ]

1 голос
/ 05 апреля 2020

Вы можете использовать регулярное выражение

import re

s = '[Carrots] [Broccoli] (cucumber)-(tomato) irrelevant [spinach]'

lst = [x[0] or x[1] for x in re.findall(r'\[(.*?)\]|\((.*?)\)', s)]
print(lst)

Выход

['Carrots', 'Broccoli', 'cucumber', 'tomato', 'spinach']

Пояснение

Шаблон регулярного выражения для сопоставления

r'\[(.*?)\]|\((.*?)\)'

Подшаблон 1: для сопоставления элементов в квадратных скобках, например [...]

\[(.*?)\]  # Use \[ and \] since  [, ] are special characters
           #  we have to escape so they will be literal
 (.*?)     # Is a Lazy match of all characters 

Подшаблон 2: для сопоставления в скобках, т. Е. (..)

\((.*?)\)   # Use \( and \) since  (, ) are special characters
            # we have to escape so they will be literal

Поскольку мы ищем любой из двух шаблонов, которые мы используем:

'|'         # which is or between the two subpatterns
            # to match Subpattern1 or Subpattern

Выражение

re.findall(r'\[(.*?)\]|\((.*?)\)', s)

[('Carrots', ''), ('Broccoli', ''), ('', 'cucumber'), ('', 'tomato'), ('spinach', '')]

Результат находится в первом или втором кортеже. Поэтому мы используем:

[x[0] or x[1] for x in re.findall(r'\[(.*?)\]|\((.*?)\)', s)]

Чтобы извлечь данные из первого или второго кортежа и поместить их в список.

0 голосов
/ 05 апреля 2020

Предполагая, что не используются никакие другие скобки или операторы (например, '-'), кроме тех, которые присутствуют в вашем примере строки, попробуйте

s = '[Carrots] [Broccoli] (cucumber)-(tomato) irrelevant [spinach]'

words = []
for elem in s.replace('-', ' ').split():
    if '[' in elem or '(' in elem:
        words.append(elem.strip('[]()'))

Или с пониманием списка

words = [elem.strip('[]()') for elem in s.replace('-', ' ').split() if '[' in elem or '(' in elem]
0 голосов
/ 05 апреля 2020

Без какой-либо обработки ошибок (например, проверка вложенных или несбалансированных скобок):

def parse(expr):
    opening = "(["
    closing = ")]"
    result = []
    current_item = ""
    for char in expr:
        if char in opening:
            current_item = ""
            continue
        if char in closing:
            result.append(current_item)
            continue
        current_item += char
    return result

print(parse("(a)(b) stuff (c) [d] more stuff - (xxx)."))

>>> ['a', 'b', 'c', 'd', 'xxx']

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

...