разбор предложения - сопоставить интонации и пропустить знаки препинания

Я пытаюсь разобрать предложения в python - для любого предложения, которое я получаю, я должен брать только слова, которые появляются после слов «сказать» или «спросить» (если слова не появляются, я должен взять все предложение) я просто сделал это с регулярными выражениями:

sen = re.search('(?s)(?<=say|Say).*$', current_game_row["sentence"], re.M | re.I)

(это только для "сказать", но добавить "спросить" не проблема...)

Проблема в том, что если я получаю предложение с такими знаками препинания, как запятая, двоеточие (,:) после слова «говорить», оно тоже принимает его. Кто-то предложил мне использовать токенизацию nltk, чтобы определить ее, но я новичок в python и не понимаю, как ее использовать. Я вижу, что в nltk есть функция RegexpParser, но я не знаю, как ее использовать. Пожалуйста помогите :-)

** Я забыл упомянуть, что я также хочу распознавать «сказал» / спросил и т. Д. И не хочу ловить слова, включающие слово «сказать» или «спросить» (я не уверен, что есть такие слова. ..). Кроме того, если where многократно 'say' или 'ask' , я хочу поймать только первый токен в предложении. **


person merav    schedule 05.02.2021    source источник
comment
Вы можете просто re.split(r'\b(?:say|ask)\b[,.;:!?]*', sentence) и проверить, является ли результат более чем одним элементом. Что должно произойти, если имеется несколько токенов «говорить» или «спрашивать»? Как насчет интонаций, как сказал и спросил?   -  person tripleee    schedule 05.02.2021
comment
Вы правы, я забыл упомянуть об этом - я хочу распознать «сказал» и т. Д. И не хочу улавливать слова, включающие слово «говорить» (я не уверен, что есть такое слово ...). Кроме того, если где многократно "сказать" или "спросить", я хочу поймать только первый токен   -  person merav    schedule 05.02.2021
comment
Таким образом, 1_. Границы слов \b предотвращают совпадение регулярного выражения в середине слова. Вам не нужно перечислять нижний и верхний регистр с помощью re.I (хотя тогда, конечно, это также будет соответствовать на aSkS и т. д.).   -  person tripleee    schedule 05.02.2021
comment
Essay — это пример слова, которое содержит say в качестве подстроки. В Ask гораздо проще найти примеры (task, basked, flasks и т. д.).   -  person tripleee    schedule 05.02.2021


Ответы (1)


Все после ключевого слова

Мы можем справиться с нежелательной пунктуацией, используя \w, чтобы поглотить все не-Юникод.

sentence = "Hearsay? With masked flasks I said: abracadabra"

keys = '|'.join(['ask', 'asks', 'asked', 'say', 'says', 'said'])
result = re.search(rf'\b({keys})\b\W+(.*)', sentence, re.S | re.I)

if result == None:
    print(sentence)
else:    
    print(result.group(2))

Выход:

abracadabra 

с учетом регистра: у вас есть флаг без учета регистра re.I, поэтому мы можем удалить перестановку Say.

многострочный: у вас есть re.M, который указывает, что ^ соответствует не только началу вашей строки, но и сразу после каждого \n в этой строке. Мы можем отказаться от этого, так как нам не нужно использовать ^.

dot-matches-all: у вас есть (?s) который предписывает . сопоставлять все, включая \n. Это то же самое, что применить флаг re.S.

Я не уверен, каков чистый эффект наличия re.M и re.S. Я думаю, что ваше предложение может быть текстовым блоком с символами новой строки внутри, поэтому я удалил re.M и оставил (?s) как re.S.

person Razzle Shazl    schedule 05.02.2021
comment
Я думаю, что ОП ищет все после того, как сказал или спросил. - person tripleee; 05.02.2021
comment
Хороший вопрос, я склонен согласиться с вами @tripleee - person Razzle Shazl; 05.02.2021