Regex: условное сопоставление подстрок в скобках - PullRequest
0 голосов
/ 20 января 2020

У меня есть набор текстов из живых телевизионных сегментов, и я пытаюсь найти способ удалить ссылки на предварительно записанные сегменты или рекламные ролики с помощью регулярных выражений. Рассмотрим следующий пример сценария симптомов c типа текста, с которым я работаю:

myconvo = "speaker1: hello

          speaker2: hello (clears throat), let me show you something Ted Cruz said last week

          (begin audio clip)

          Ted Cruz (R-TX): My dad did not shoot JFK, why do people keep saying that?

          (end audio clip)

          speaker1: now isn't that interesting"

Корпус был создан из разных источников с разными стандартами (то есть одни используют скобки, другие используют скобки это один пример). Тем не менее, вышеизложенное является широким представлением. Чтобы решить эту проблему, я написал следующее:

cleanString = re.sub(r"\n[\(\[].+[\)\]]\n*[\.a-zA-Z\s\d,'’:;!?@£$\"“”-]*\n*[\(\[].+[\)\]]", '', myconvo)

Для ясности этот сценарий написан для выполнения следующих действий:

1. Поиск новой строки с последующим открывающими / закрывающими скобками / круглыми скобками с текстом между ними (где текст обозначает начало сегмента \n[\(\[.+][\)\]]

2. Ищите любое количество новых строк, за которыми следует текст, соответствующий удаляемый сегмент \n*[\.a-zA-Z\s\d,'’:;!?@£$\"“”-]*

3. Ищите новую строку, за которой следуют скобки / скобки, содержащие конец удаляемого сегмента

4. Заменить пробелом

Это работает, поскольку удаляемый текст не содержит круглых скобок, однако он полностью портится с выводом (если это и число) других у меня будет).

Мне интересно, есть ли способ, которым я могу указать текст, который будет применяться только в начале строки, но я не уверен, как go об этом. Также укажу, что это мои ели Я не могу найти ничего подобного, поэтому, если у кого-то есть лучший обходной путь, я очень приветствую вклад.

РЕДАКТИРОВАТЬ: Для ясности, я хотел бы получить в итоге:

myconvo = "speaker1: hello

      speaker2: hello (clears throat), let me show you something Ted Cruz said last week

      speaker1: now isn't that interesting"

Ответы [ 3 ]

0 голосов
/ 20 января 2020

Ваша строка myconvo не является допустимой Python строкой. Но угадав, глядя на ваше регулярное выражение, что (begin audio clip) и (end audio clip) начинаются после символов новой строки и заканчиваются символами новой строки, вы можете попробовать:

r'\n\([^()]+\)\n.*?\n\([^()]+\)\n' with flags re.DOTALL
  1. \n Соответствует новой строке.
  2. \( Соответствует (.
  3. [^()] + Соответствует 1 или более символам, которые не ( или ).
  4. ) Соответствует ).
  5. \n Соответствует новой строке.
  6. '. *? `Минимальное совпадение, которое будет соответствовать чему-либо до следующего.
  7. \n Соответствует новой строке .
  8. \( Соответствует (.
  9. [^()] + Соответствует 1 или более символам, которые не ( или ).
  10. ) Совпадения ).
  11. \n Совпадения с новой строки.

См. Regex Demo

Код:

import re

myconvo = """speaker1: hello

speaker2: hello (clears throat), let me show you something Ted Cruz said last week

(begin audio clip)

Ted Cruz (R-TX): My dad did not shoot JFK, why do people keep saying that?

(end audio clip)

speaker1: now isn't that interesting"""

myconvo = re.sub(r'\n\([^()]+\)\n.*?\n\([^()]+\)\n', '', myconvo, flags=re.DOTALL)
print(myconvo)

Отпечатки:

speaker1: hello

speaker2: hello (clears throat), let me show you something Ted Cruz said last week

speaker1: now isn't that interesting
0 голосов
/ 20 января 2020

Если вы также хотите учесть опцию, начинающуюся с пробелов в примере, вы можете также сопоставить их.

Чтобы избежать проблемы, если текст также содержит скобки или скобки, вы можете сопоставить все промежуточные строки, которые не начинаются с одной, использующей отрицательный символ (?![^\S\r\n]*[\[\]()]).

Для соответствия 0+ пробелам вы можете использовать класс отрицательных символов [^\S\r\n]*, соответствующий не непробельному символу кроме новой строки.

Обратите внимание , что совпадение [ и ( в том же классе символов, а также ] и ) также может совпадать с [ для открытия и ) для закрытия.

\r?\n[^\S\r\n]*[([].+[)\]](?:\r?\n(?![^\S\r\n]*[\[\]()]).*)*\r?\n[^\S\r\n]*[\{(].+\n

Regex demo | Python demo

Ваш код может выглядеть следующим образом:

import re 
myconvo = """speaker1: hello

          speaker2: hello (clears throat), let me show you something Ted Cruz said last week

          (begin audio clip)

          Ted Cruz (R-TX): My dad did not shoot JFK, why do people keep saying that?

          (end audio clip)

          speaker1: now isn't that interesting"""


regex = r"\r?\n[^\S\r\n]*[([].+[)\]](?:\r?\n(?![^\S\r\n]*[\[\]()]).*)*\r?\n[^\S\r\n]*[\{(].+\n"
result = re.sub(regex, "", myconvo)
print (result)

Вывод

speaker1: hello

          speaker2: hello (clears throat), let me show you something Ted Cruz said last week

          speaker1: now isn't that interesting

Если все строки не имеют пробелы в начале, вы могли бы быть:

\r?\n[([].+[)\]](?:\r?\n(?![\[\]()]).*)*\r?\n[\{(].+\r?\n

Regex demo

0 голосов
/ 20 января 2020

Вы можете попробовать:

import re

myconvo = """speaker1: hello

          speaker2: hello (clears throat), let me show you something Ted Cruz said last week

          (begin audio clip)

          Ted Cruz (R-TX): My dad did not shoot JFK, why do people keep saying that?

          (end audio clip)

          speaker1: now isn't that interesting"""

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):    
    myconvo = myconvo[0:match.start()] + myconvo[match.end():]
print(myconvo)

Дает вывод

speaker1: hello

          speaker2: hello (clears throat), let me show you something Ted Cruz said    (begin audio clip)

          Ted Cruz (R-TX): My dad did not shoot JFK, why do people kee          (end audio clip)

          speaker1: now isn't that interesting
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...