Ненасытное регулярное выражение 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 3

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