Регулярное выражение Python: вернуть все предложение с определенным словом в нем от периода к периоду

Ниже приведено предложение, которое я хочу обработать. Он состоит из идентификаторов, которые начинаются с двух решеток впереди (##2312435) плюс оставшийся текст. Мне нужно регулярное выражение, которое будет находить предложения со словом likely в них и извлекать все предложение вместе с идентификатором.

Предложение:

##2312435 Джона нет дома. Джон, скорее всего, вернется домой после полуночи. Еще одно не связанное предложение. ##2233442 Марк очень зол. Марк, вероятно, выпьет пива сегодня вечером.

Мне удалось написать это:

(?=.\*((?<=##)\d+))(?=.*([^.]+(likely)+[^.]+))

но это не возвращает полное предложение.

Ожидаемый результат будет выглядеть так: 2312435 Джон, скорее всего, вернется домой после полуночи, 2233442 Марк, вероятно, сегодня вечером выпьет пива.

Я спрашиваю это только для общего ознакомления, потому что я изо всех сил пытаюсь справиться с поиском. Я уже решил это без регулярного выражения, но я подумал, что могу попробовать и попытаться получить необходимую информацию с помощью регулярного выражения. Спасибо


person Rkey    schedule 08.06.2016    source источник
comment
вы понимаете, что вам не нужно регулярное выражение для всего этого?   -  person glls    schedule 08.06.2016
comment
Да, я понимаю, я уже делал это без них, но я хотел попрактиковаться с регулярным выражением и не мог решить это.   -  person Rkey    schedule 08.06.2016
comment
Ok. возможно, вы захотите добавить это в свой пост, и, пожалуйста, добавьте то, что вы ожидаете от своего регулярного выражения (пример)   -  person glls    schedule 08.06.2016
comment
После ## может встречаться несколько предложений с likely, а идентификатор находится в самом предложении. Вам нужен ##id и каждое из этих предложений или только первое?   -  person bobble bubble    schedule 08.06.2016
comment
Каждому из них спасибо.   -  person Rkey    schedule 08.06.2016
comment
Возможно, это можно сделать с помощью Python модуля регулярных выражений с помощью просмотра назад переменной длины или \G привязка, как в этой попытке (regex101), но, вероятно, есть лучшие решения. Еще одна проблема, о которой вообще не упоминалось, — разбор предложения на естественном языке.   -  person bobble bubble    schedule 08.06.2016


Ответы (3)


Так что это очень некрасиво и работает только в том случае, если есть только одно предложение со словом likely:

re.findall(r'##(\d+)(?:[^#]*\.)*([^#.]*?likely[^#.]*?)\.', text, re.IGNORECASE)

# Output:
#[('2312435', ' John is likely to come home after midnight'),
# ('2233442', ' Mark is likely to have a beer tonight')]
person AndreyT    schedule 08.06.2016

p = re.compile(r'^##\d+.*likely.*$')
res = p.match(t).group().replace('##','')

Например,

>>> t = '##2312435 Jon is not home. John is likely to come home after midnight. Another not related sentence. ##2233442 Mark is very angry. Mark is likely to have a beer tonight.'
>>> p = re.compile(r'^##\d+.*likely.*$')
>>> res = p.match(t).group().replace('##','')
>>> print res
2312435 Jon is not home. John is likely to come home after midnight. Another not related sentence. 2233442 Mark is very angry. Mark is likely to have a beer tonight.
person Rahul    schedule 08.06.2016

Любое регулярное выражение для этой задачи будет выглядеть некрасиво, но мы можем сделать его как минимум эффективным.

Основное регулярное выражение состоит в том, чтобы сопоставить ## + цифры, захватить эти цифры, затем сопоставить любой текст, который не является ## + цифрой, затем likely, а затем снова любой текст, который не является ## + цифрой.

##(\d+)\s*((?:(?!##\d).)*\blikely\b(?:(?!##\d).)*)

См. демонстрацию регулярного выражения. (?:(?!##\d).)* — это умеренный жадный токен, довольно тяжелый для механизма регулярных выражений.

Мы можем развернуть его, чтобы повысить производительность, например:

##(\d+)\s*([^#]*(?:#(?!#\d)[^#]*)*\blikely\b[^#]*(?:#(?!#\d)[^#]*)*)

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

Это все еще не так эффективно, и если вам не нужно проверять целое слово likely, вы можете использовать

##(\d+)\s*([^#l]*(?:#(?!#\d)[^l#]*|l(?!ikely)[^l#]*)*likely[^#]*(?:#(?!#\d)[^#]*)*)

См. еще другое регулярное выражение.

person Wiktor Stribiżew    schedule 08.06.2016