【问题标题】:Python: How to find n-gram patterns in the text?Python:如何在文本中找到 n-gram 模式?
【发布时间】:2012-03-06 08:57:12
【问题描述】:

我有一个可以任意长的字符串

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

我们如何处理这个问题?

【问题讨论】:

标签: python regex nltk


【解决方案1】:
p = re.compile('|'.join(re.escape(w) for w in p_words))

p 将匹配p_words 中的任何字符串。

【讨论】:

  • 没有理由不这样做。
  • @J.F.Sebastian 如果您将re.finditerre.findall 与生成的正则表达式一起使用。
  • @Amber: re.find* 枚举匹配项,但仍然自己不回答“多少次”。
  • @JFSebastian - 鉴于 OP 在不针对 ngram 时已经在使用正则表达式来解决他们的问题,因此假设他们能够根据需要实现计数部分似乎是合乎逻辑的。跨度>
【解决方案2】:

如果文字和字数不是很大可以从example开始:

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

输出

  2 cash
  2 limited time offer

【讨论】:

  • 感谢@J.F.Sebastian 告诉我存在计数器,我不知道
  • @daydreamer:注意Counter 不是最快的,如果你使用这个算法:performance comparison
【解决方案3】:

正则表达式使用“|”分隔器。将每种情况下的空格替换为 '\W+' 之类的东西,它匹配非字母,我认为你很高兴。

【讨论】:

    猜你喜欢
    • 2018-08-12
    • 2015-05-31
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 2013-11-25
    • 2012-01-05
    相关资源
    最近更新 更多