【问题标题】:Word frequency in a string without spaces and with special characters?没有空格和特殊字符的字符串中的词频?
【发布时间】:2014-03-21 02:05:10
【问题描述】:

假设我有以下字符串:

"hello&^uevfehello!`.<hellohow*howdhAreyou"

我将如何计算作为它的子字符串的英语单词的频率?在这种情况下,我想要一个结果,例如:

{'hello': 3, 'how': 2, 'are': 1, 'you': 1}

我搜索了与此类似的上一个问题,但我找不到任何有效的方法。一个接近的解决方案似乎是使用正则表达式,但它也不起作用。这可能是因为我实施错误,因为我不熟悉它的实际工作原理。

How to find the count of a word in a string? 这是最后一个答案

from collections import *
import re

Counter(re.findall(r"[\w']+", text.lower()))

我还尝试创建一个非常糟糕的函数,它遍历字符串中每个可能的连续字母排列(最多 8 个字母左右)。这样做的问题是

1) 它比应有的长得多并且

2) 它添加了额外的单词。例如:如果字符串中有“hello”,也会找到“hell”。

我对正则表达式不是很熟悉,这可能是正确的方法。

【问题讨论】:

  • 要统计英文单词的出现频率,这还不够。你必须使用ntlk 之类的东西,即使那样也很难,因为你没有单词分隔符。
  • 你有识别英文单词的函数或字典吗?
  • 我有一个英文单词列表,我正在比较字符串的一部分,但它并没有太大帮助。
  • @Howcan 请给我们看看你的英文单词列表。

标签: python regex string


【解决方案1】:
d, w = "hello&^uevfehello!`.<hellohow*howdhAreyou", ["hello","how","are","you"]
import re, collections
pattern = re.compile("|".join(w), flags = re.IGNORECASE)
print collections.Counter(pattern.findall(d))

输出

Counter({'hello': 3, 'how': 2, 'you': 1, 'Are': 1})

【讨论】:

  • @JayanthKoushik RegEx 我相信在内部使用状态机。所以,我不太确定复杂性。 :(
  • 您正在使用已知单词列表来比较 (w),所以从技术上讲,我必须使用英语单词列表?
  • @Howcan 这就是我从你的comment 中了解到的
  • 你可以使用字典或像 enchant 之类的库来进行 O(1) 的比较。
【解决方案2】:
from collections import defaultdict

s = 'hello&^uevfehello!`.<hellohow*howdhAreyou'
word_counts = defaultdict(lambda: 0)

i = 0
while i < len(s):
    j = len(s)
    while j > i:
        if is_english_word(s[i:j]):
            word_counts[s[i:j]] += 1
            break
        j -= 1

    if j == i:
        i += 1
    else:
        i = j

print word_counts

【讨论】:

    【解决方案3】:

    您需要从字符串中提取所有单词,然后为每个单词查找子字符串,然后检查是否有任何子字符串是英文单词。我在How to check if a word is an English word with Python?中使用了来自答案的英语词典

    但是结果中有一些误报,因此您可能希望使用更好的字典或使用自定义方法来检查所需的单词。

    import re
    import enchant
    from collections import defaultdict
    
    # Get all substrings in given string.
    def get_substrings(string):
        for i in range(0, len(string)):
            for j in range(i, len(string)):
                yield s[i:j+1]
    
    text = "hello&^uevfehello!`.<hellohow*howdhAreyou"
    
    strings = re.split(r"[^\w']+", text.lower())
    
    # Use english dictionary to check if a word exists.
    dictionary = enchant.Dict("en_US")
    counts = defaultdict(int)
    for s in strings:
      for word in get_substrings(s):
          if (len(word) > 1 and dictionary.check(word)):
              counts[word] += 1
    
    print counts
    

    输出:

    defaultdict(, {'are': 1, 'oho': 1, 'eh': 1, 'ell': 3, 'oh': 1, 'lo': 3, 'll': 3, 'yo': 1, 'how': 2, 'hare': 1, 'ho': 2, 'ow': 2, 'hell': 3, 'you': 1, 'ha': 1, 'hello': 3, 're': 1, 'he': 3})

    【讨论】:

    • 但这不是我们想要的输出。如果 Hell 后跟一个 o 等,则应忽略它。一般情况下,应忽略字符串中其他单词的子串的所有单词。
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 2014-08-17
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2011-08-16
    相关资源
    最近更新 更多