Regex Lookahead и просмотр нескольких раз в Python - PullRequest
0 голосов
/ 24 октября 2019

У меня есть входные данные, отформатированные как показано ниже (txt1):

txt1 = "[('1','Hello is 1)people 2)animals'), ('People are 1) hello 2) animals'), ('a')]"

Я хочу извлечь его в следующем формате -

[['1','Hello is 1)people 2)animals'],['People are 1) hello 2) animals'],['a']]

Итак, в основном, я хочу получить информацию в скобках. Но я не смог этого сделать. Кроме того, я использовал Lookahead и Lookbehind, чтобы избежать разбиения по номерам - «1)» или «2)», что произошло раньше, когда я сделал простое утверждение re.split('[\(\)\[\]]

Я пытался findall сначала проверяет, что я получаю.

r = re.findall(r'\((?=\').*(?<=\')\)(?=\,)', txt1)

Я получаю -

["('1','Hello is 1)people 2)animals'), ('People are 1) hello 2) animals')"]

Кажется, что игнорирует среднюю скобку. Что я могу сделать, чтобы получить нужный мне результат?

Спасибо.

Примечание:

Для функции разделения, которую я намереваюсьиспользовать для получения желаемого выхода, я получаю это -

r = re.split(r'\((?=\').*(?<=\')\)(?=\,)', txt1)

['[', ", ('a')]"]

Ответы [ 3 ]

1 голос
/ 24 октября 2019

Вы можете попробовать с шаблоном \(([^(]+)\)

Объяснение:

\( - совпадение ( буквально

(...) - группа захвата

[^(]+ - сопоставить один или несколько символов другим из (

\) - сопоставить ) буквально

и использовать шаблон замены: [\1], который ставит первый захватгруппа (обратная ссылка \1) внутри квадратных скобок.

Демо

0 голосов
/ 24 октября 2019

Другое решение без необходимости использования regex:

txt1 = "[('1','Hello is 1)people 2)animals'), ('People are 1) hello 2) animals'), ('a')]"
replace_pairs = {
    "('": "'",
    "'), ": '#',
    '[': '',
    ']': '',
    "'": '',
}
for k, v in replace_pairs.items():
    txt1 = txt1.replace(k, v)

txt1 = txt1[:-1].split('#') # the last char is a paranthesis
print([i.split(',') for i in txt1])

Вывод:

[['1', 'Hello is 1)people 2)animals'], ['People are 1) hello 2) animals'], ['a']]

Примечание. Это может не работать, если ввод более сложный, чем тот, который вы используетепоказано здесь.

0 голосов
/ 24 октября 2019

Почему регулярное выражение?

import ast
[list(x) if isinstance(x, tuple) else [x] for x in ast.literal_eval(txt1)]
# => [['1', 'Hello is 1)people 2)animals'], ['People are 1) hello 2) animals'], ['a']]

Если вы настаиваете на регулярных выражениях, это должно работать, если строки не содержат экранированных кавычек:

[re.findall(r"'[^']*'", x) for x in re.findall(r"\(('[^']*'(?:,\s*'[^']*')*)\)", txt1)]
# => [["'1'", "'Hello is 1)people 2)animals'"], ["'People are 1) hello 2) animals'"], ["'a'"]]
...