Ненасытное регулярное выражение python
Я пытаюсь работать с некоторыми регулярными выражениями; я использую python.
Моя задача сейчас состоит в том, чтобы соскребать газетные статьи и искать случаи, когда люди умирали. Как только у меня появится соответствующая статья, я попытаюсь поймать счет смерти для некоторых других вещей. Я пытаюсь придумать несколько моделей, но у меня возникают трудности с одной из них. Возьмем этот пример раздела статьи:САНА, 21 октября (Reuters) - трое мужчин, предположительно из "Аль-Каиды". мятежники были убиты в результате атаки американского беспилотника на автомобиль в Йемене. Об этом в воскресенье сообщили источники в племенах и местные чиновники.
Код, который я использую, чтобы поймать " три "сначала делает замену на весь документ, так что" три "становится " 3", прежде чем какие-либо шаблоны вообще применяются. Паттерн, относящийся к этому примеру, таков:
re.compile(r"(d+)s(:?men|women|children|people)?.*?(:?were|have been)? killed")
Идея заключается в том, что этот шаблон будет начинаться с числа, за которым последует необязательное существительное, такое как одно из перечисленных, а затем имейте минимальное количество беспорядка, прежде чем найти "мертвого" или "умершего". Я хочу оставить место так, чтобы этот паттерн уловил:
3 people have been killed since Sunday
И все же поймать экземпляр в Примере:
3 men thought to be al qaeda militants were killed
Проблема в том, что шаблон, который я использую, собирает дату из первой части статьи и возвращает число 21. Никакое количество манипуляций до сих пор не позволило мне ограничить область действия цифрой рядом со словом men, за которой следует причастная фраза, а затем соответствующее "were убит".
Любая помощь была бы очень признательна. Я определенно не гуру, когда дело доходит до огня.3 ответа:
Не делайте
men|women|childrenнеобязательным, то есть уберите знак вопроса после закрывающей скобки. Механизм регулярных выражений будет соответствовать первому возможному месту, независимо от того, жадны ли операторы повторения или скупы.Альтернативно или дополнительно, сделайте шаблон "что-нибудь здесь" только совпадающим с не-числами, т. е. замените
.*?на\D*?
Это потому, что вы использовали Квантор
?, который соответствует0или1Вашего(:?men|women|children|people)после вашей цифры. Итак,21будет соответствовать. так как он имеет0из них.Попробуйте удалить свой Квантор после него, чтобы точно соответствовать одному из них: -
re.compile(r"(\d+)\s(?:men|women|children|people).*?(?:were|have been)? killed")UPDATE: - чтобы использовать
? quantifierи все же получить требуемый результат, вам нужно использоватьLook-Aheadрегулярное выражение, чтобы убедиться, что за вашимdigitне следует строка, содержащаяhiephen(-), как в вашем примере.re.compile(r"(\d+)(?!.*?-.*?)\s(?:men|women|children|people)?.*?(?:were|have been)? killed")
Вы используете неправильный синтаксис
(:?...). Вы, вероятно, хотели использовать(?:...).
Использовать шаблон регулярных выражений
(\d+).*?\b(?:men|women|children|people|)\b.*?\b(?:were|have been|)\b.*?\bkilled\bИли если между этими словами допускаются только пробелы, то
(\d+)\s+(?:men|women|children|people|)\s+(?:were|have been|)\s+killed\b