Python: Как найти n-граммовые шаблоны в тексте? - PullRequest
2 голосов
/ 15 февраля 2012

У меня есть строка, которая может быть произвольно длинной, скажем

s = 'Choose from millions of possibilities on Shaadi.com. Create your profile, search&contact; your special one.RegisterFree\xa0\xa0\xa0unsubscribing reply to this mail\xa0\n and 09times and this is limited time offer! and this is For free so you are saving cash'

У меня есть список спам-слов, которые могут быть похожи на

p_words = ['cash', 'for free', 'limited time offer']

Все, что я хочу знать, существует ли шаблон во входном тексте и сколько раз?

Становится просто, когда в нем всего одно слово

import re
p = re.compile(''.join[p_words])  # correct me if I am wrong here
m = p.match(s)  

но это может быть bi-gram, tri-gram or n-gram

Как мы подходим к этому?

Ответы [ 3 ]

4 голосов
/ 15 февраля 2012
p = re.compile('|'.join(re.escape(w) for w in p_words))

p будет соответствовать любой из строк в p_words.

2 голосов
/ 15 февраля 2012

Если текст и количество слов не очень велики, вы можете начать с пример :

d = {w: s.count(w) for w in p_words if w in s}
# -> {'cash': 1, 'limited time offer': 1}

Вы можете сравнить его производительность с:

import re
from collections import Counter

p = re.compile('|'.join(map(re.escape, p_words)))
d = Counter(p.findall(s))
# -> Counter({'limited time offer': 2, 'cash': 2})

Для справки сравните его скорость с fgrep.Он должен быть быстрым при сопоставлении нескольких строк во входном потоке:

$ grep -F -o -f  patternlist.txt largetextfile.txt  | sort | uniq -c

Output

  2 cash
  2 limited time offer
1 голос
/ 15 февраля 2012

регулярные выражения используют '|'разделитель.Замените пробелы в каждом случае чем-то вроде '\ W +', что соответствует не буквам, и я думаю, что вы готовы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...