Регулярное выражение Python, не жадный, действующий как жадный - PullRequest
0 голосов
/ 02 мая 2018

Я работаю с расшифровками и испытываю проблемы с сопоставлением шаблонов без жадности. Это все еще слишком много и похоже на жадные матчи.

Стенограмма выглядит так:

>> Джон Доу: Здравствуйте, я Джон Доу.

>> Здравствуйте, я Джейн Доу.

>> Спасибо, что пришли, мы начнем через две минуты.

>> Сэм Смит: [без звука] Доброе утро всем.

Чтобы найти имя оратора в >> (WHATEVER NAME) :, я написал

pattern=re.compile(r'>>(.*?):')
transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'
re.findall(pattern, transcript)

Я ожидал 'John Doe' и 'Sam Smith', но это дает мне 'John Doe' и 'Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith'

Я запутался, потому что .*? не жадный, который (я думаю) должен быть в состоянии схватить 'Sam Smith'. Как я должен исправить код, чтобы он захватывал только то, что в >> (КАКОЕ ИМЯ) :? Также я использую Python 3.6.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Ваше понимание не-жадного регулярного выражения немного неверно. Нежадность означает, что она будет соответствовать кратчайшему возможному совпадению с момента начала сопоставления. Он не изменит персонажа, с которым он начинает сопоставлять, если в матче найден другой.

Например:

start.*?stop

Будет соответствовать всем startstartstop, потому что, как только оно начинает совпадать с start, оно будет продолжать совпадение, пока не найдет остановку. Нежадность просто означает, что для строки startstartstopstop она будет соответствовать только до первой остановки.

По вашему вопросу, эту проблему легко решить, используя позитивный взгляд.

Вы можете использовать >> ([a-zA-Z ]+)(?=:):

>>> transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'    
>>> re.findall(r'>> ([a-zA-Z ]+)(?=:)', transcript)
['John doe', 'Sam Smith']
0 голосов
/ 02 мая 2018

Вам действительно нужно регулярное выражение? Вы можете разделить запросы >>, а затем отфильтровать свои имена.

>>> [i.split(':')[0].strip() for i in transcript.split('>>') if ':' in i]
['John doe', 'Sam Smith']
...