Разбор текста с помощью Python RegEx re.findall

У меня есть длинная строка, которую мне нужно разобрать по группам, но мне нужно больше контролировать ее.

import re

RAW_Data = "Name Multiple Words Testing With 1234 Numbers and this stuff* ((Bla Bla Bla (Bla Bla) A40 & A41)) Name Multiple Words Testing With 3456 Numbers and this stuff2* ((Bla Bla Bla (Bla Bla) A42 & A43)) Name Multiple Words Testing With 78910 Numbers and this stuff3* ((Bla Bla Bla (Bla Bla) A44 & A45)) Name Multiple Words Testing With 1234 Numbers and this stuff4* ((Bla Bla Bla (Bla Bla) A46 & A47)) Name Multiple Words Testing With 1234 Numbers and this stuff5* ((Bla Bla Bla (Bla Bla) A48 & A49)) Name Multiple Words Testing With 1234 Numbers and this stuff6* ((Bla Bla Bla (Bla Bla) A50 & A51)) Name Multiple Words Testing With 1234 Numbers and this stuff7* ((Bla Bla Bla (Bla Bla) A52 & A53)) Name Multiple Words Testing With 1234 Numbers and this stuff8* ((Bla Bla Bla (Bla Bla) A54 & A55)) Name Multiple Words Testing With 1234 Numbers and this stuff9* ((Bla Bla Bla (Bla Bla) A56 & A57)) Name Multiple Words Testing With 1234 Numbers and this stuff10* ((Bla Bla Bla (Bla Bla) A58 & A59)) Name Multiple Words Testing With 1234 Numbers and this stuff11* ((Bla Bla Bla (Bla Bla) A60 & A61)) Name Multiple Words Testing With 1234 Numbers and this stuff12* ((Bla Bla Bla (Bla Bla) A62 & A63)) Name Multiple Words Testing With 1234 Numbers and this stuff13* ((Bla Bla Bla (Bla Bla) A64 & A65)) Name Multiple Words Testing With 1234 Numbers and this stuff14* ((Bla Bla Bla (Bla Bla) A66 & A67)) Name Multiple Words Testing With 1234 Numbers and this stuff15* ((Bla Bla Bla (Bla Bla) A68 & A69)) Name Multiple Words Testing With 1234 Numbers and this stuff16*"

fromnode = re.findall('(.*?)(?=\*\s)', RAW_Data)

print fromnode

del fromnode
del RAW_Data

Результаты: 'Тестирование имени нескольких слов с использованием 1234 цифр и прочего', '', ' ((Бла-бла-бла (Бла-бла) A40 и A41)) Проверка имени нескольких слов с помощью 3456 цифр и прочего2' . ....... и так далее.

Кажется, я не могу зафиксировать только такие строки, как «Тестирование нескольких слов с помощью 3456 чисел и прочего», и опустить все строки, такие как «((Bla Bla Bla (Bla Bla) A40 и A41))». Любая помощь приветствуется.


person user1457123    schedule 28.04.2016    source источник
comment
Будет ли элемент Bla... всегда заключен в круглые скобки, а формулировка Name Mul... всегда будет идентичной?   -  person schwobaseggl    schedule 28.04.2016
comment
Вам просто нужны вещи за скобками?   -  person Laurel    schedule 28.04.2016
comment
Да, материал Bla Bla Bla всегда будет структурирован в двойных скобках. Там также есть группа одинарных скобок. Я использую другой re.findall(('((((.*?)))', RAW_Data) для захвата этих разделов. Пока я хочу их игнорировать. Имя Mul.... не всегда будет одинаковым. сбросил туда какой-то текст, чтобы было несколько слов, пробелов и цифр, как своего рода уловка.   -  person user1457123    schedule 28.04.2016
comment
@ Лорел, да, я хочу только то, что не в скобках. Что-то вроде всех групп проверки имени нескольких слов с помощью 1234 чисел и прочего, проверки имени нескольких слов с помощью 1234 чисел и прочего2 и т. д.   -  person user1457123    schedule 28.04.2016
comment
А нельзя просто заменить все в скобках почему?   -  person Laurel    schedule 28.04.2016
comment
Я попытался заменить все в скобках только на a, но он не возвращал совпадения в виде отдельных строк. Это была всего лишь одна длинная строка без разделов, которые мне не нужны. Все это выполняется в цикле, который обновляет несколько полей в таблице проанализированным текстом.   -  person user1457123    schedule 29.04.2016
comment
@ user1457123: Мой ответ тебе не подходит? Вам нужны совпадения в виде отдельных строкre.split предоставляет вам список тех подстрок, которые вы ищете.   -  person Wiktor Stribiżew    schedule 29.04.2016
comment
Виктор, у меня еще не было возможности проверить это. Я попробую первым делом утром, когда вернусь в офис. Спасибо всем за помощь.   -  person user1457123    schedule 29.04.2016
comment
Виктор работал как чемпион. В итоге я использовал первое предложение как re.split. Еще раз спасибо всем за помощь   -  person user1457123    schedule 29.04.2016


Ответы (1)


Вы можете разделить с

r'\*\s*\({2}.*?\){2}\s*'

Шаблон (см. демонстрацию) соответствует:

  • \* - буквальная звездочка
  • \s* - ноль или более пробелов
  • \({2} - ровно 2 открывающие скобки
  • .*? - ноль или более символов, кроме новой строки (ПРИМЕЧАНИЕ: добавьте флаг re.S, если вам нужно сопоставить несколько строк) как можно меньше до первой
  • \){2} - двойные закрывающие скобки
  • \s* - 0+ пробелов.

ТАКЖЕ: то же самое, но развернутое (таким образом, более эффективное) регулярное выражение:

\*\s*\({2}[^)]*(?:\)(?!\))[^)]*)*\){2}\s*

См. демонстрацию IDEONE:

import re
p = re.compile(r'\*\s*\({2}.*?\){2}\s*')
test_str = "Name Multiple Words Testing With 1234 Numbers and this stuff* ((Bla Bla Bla (Bla Bla) A40 & A41)) Name Multiple Words Testing With 3456 Numbers and this stuff2* ((Bla Bla Bla (Bla Bla) A42 & A43)) Name Multiple Words Testing With 78910 Numbers and this stuff3* ((Bla Bla Bla (Bla Bla) A44 & A45)) Name Multiple Words Testing With 1234 Numbers and this stuff4* ((Bla Bla Bla (Bla Bla) A46 & A47)) Name Multiple Words Testing With 1234 Numbers and this stuff5* ((Bla Bla Bla (Bla Bla) A48 & A49)) Name Multiple Words Testing With 1234 Numbers and this stuff6* ((Bla Bla Bla (Bla Bla) A50 & A51)) Name Multiple Words Testing With 1234 Numbers and this stuff7* ((Bla Bla Bla (Bla Bla) A52 & A53)) Name Multiple Words Testing With 1234 Numbers and this stuff8* ((Bla Bla Bla (Bla Bla) A54 & A55)) Name Multiple Words Testing With 1234 Numbers and this stuff9* ((Bla Bla Bla (Bla Bla) A56 & A57)) Name Multiple Words Testing With 1234 Numbers and this stuff10* ((Bla Bla Bla (Bla Bla) A58 & A59)) Name Multiple Words Testing With 1234 Numbers and this stuff11* ((Bla Bla Bla (Bla Bla) A60 & A61)) Name Multiple Words Testing With 1234 Numbers and this stuff12* ((Bla Bla Bla (Bla Bla) A62 & A63)) Name Multiple Words Testing With 1234 Numbers and this stuff13* ((Bla Bla Bla (Bla Bla) A64 & A65)) Name Multiple Words Testing With 1234 Numbers and this stuff14* ((Bla Bla Bla (Bla Bla) A66 & A67)) Name Multiple Words Testing With 1234 Numbers and this stuff15* ((Bla Bla Bla (Bla Bla) A68 & A69)) Name Multiple Words Testing With 1234 Numbers and this stuff16*"
print(re.split(p, test_str))

ОБНОВЛЕНИЕ

Регулярное выражение для использования с re.findall:

(?:\*\s*\(\([^)]*(?:\)(?!\))[^)]*)*\)\))?\s*([^*]*(?:\*(?!\s*\(\()[^*]*)*)\s*

См. демонстрацию регулярного выражения.

В ужасе от внешнего вида? Это всего лишь развернутая версия гораздо более простого (?:\*\s*\(\(.*?\)\))?\s*(.*?(?=\*\s*(?:\(\(|$))).

См. демонстрацию IDEONE.

person Wiktor Stribiżew    schedule 28.04.2016
comment
Я добавил шаблон для использования с re.findall. Теперь, я думаю, на вопрос дан ответ. - person Wiktor Stribiżew; 29.04.2016
comment
Еще раз спасибо Виктор. Я пошел дальше и запустил предложение re.findall. Это также работает. Единственное, что я заметил, это то, что он захватил один пробел в конце. - person user1457123; 29.04.2016
comment
Пожалуйста, поделитесь входной строкой, и я позабочусь об этом. - person Wiktor Stribiżew; 29.04.2016
comment
Я использовал ту же строку ввода, что и первоначально опубликованная. Но не беспокойтесь. Решение re.split дает мне то, что мне нужно. Спасибо - person user1457123; 29.04.2016
comment
Пустое место, да? Попробуйте (?!$)(?:\*\s*\(\([^)]*(?:\)(?!\))[^)]*)*\)\))?\s*([^*]*(?:\*(?!\s*\(\()[^*]*)*)\s*. - person Wiktor Stribiżew; 29.04.2016
comment
Что ж, как и ожидалось, реальные данные, которые я анализирую, были введены не очень чистым способом. Итак, теперь мне нужно выяснить, как обойти отсутствующий . Иногда он есть, а иногда нет. Я подумал об изменении исходных данных, чтобы включить везде, где его нет. - person user1457123; 29.04.2016
comment
Если вы хотите остановиться только на скобках в качестве разделителя, попробуйте использовать (?s)(?:\*?\s*\(\(.*?\)\))?\s*(.*?(?=\*?\s*(?:\(\(|$))) - person Wiktor Stribiżew; 29.04.2016
comment
Обновить - добавив вторую * после '*....., которая позволила зафиксировать, существует ли * или нет. Я новичок и не могу понять, как правильно копировать/вставлять код в комментарии. - person user1457123; 29.04.2016
comment
Чтобы вставить код в комментарии, используйте `code`: code. Однако разве (?!$)(?:\*?\s*\(\([^)]*(?:\)(?!\))[^)]*)*\)\))?\s*([^(]*(?:\((?!\()[^(]*)*)\s* не работает? - person Wiktor Stribiżew; 01.05.2016