【问题标题】:What's the best way to count alphanumeric words?计算字母数字单词的最佳方法是什么?
【发布时间】:2020-04-25 08:33:51
【问题描述】:

我正在尝试找到在不使用正则表达式的情况下计算字母数字单词的最佳方法,这就是我所做的。

for line in csv:
        total_lines += 1
        total_words = len(line.split())
        line_char_count =  sum(map(str.isalnum, line.split()))
        line_details.append("Line %d has %d Alphanumeric word/s" % (total_lines, line_char_count))

for line in line_details:
print (line)

它不计算字母数字词,而是排除字母数字词并计算非字母数字词。所以我尝试了另一种方法:

for line in csv:
        total_lines += 1
        total_words = len(line.split())
        line_char_count =  sum(map(str.isalnum, line.split()))
        count = total_words - line_char_count
        line_details.append("Line %d has %d Alphanumeric word/s" % (total_lines, count))

for line in line_details:
print (line)

我从字符串的总字数中扣除了 line_char_count。现在,它给了我一个接近的答案,但标点符号仍然被计算在内。我不知道去除标点符号的最佳方法是什么。 或者,如果您有更好的方法来计算字母数字单词,请帮助我。 谢谢

【问题讨论】:

  • 这很难回答,因为不清楚您所说的字母数字词是什么意思。例如,如果单词被引号括起来,它是否算数?因为那不是严格的字母数字。如果这个词有撇号,它算数吗?写“轻松”是一两个字吗?
  • 使用split() 方法的解决方案由于句号而错过计算句子的最后一个单词可能是该方法中最明显的缺陷。除了特德已经注意到的情况。此外,您可能还想计算由许多其他字符分隔的单词,例如斜线“动物/宠物”.. 列表还在继续。
  • @TedKleinBergman 字母数字,如 l8ter、2go、2night 之类的
  • @Todd 哦,所以我真的应该排除标点符号。谢谢

标签: python alphanumeric


【解决方案1】:

这是在假设“word”是任何非空白字符的字符串的情况下编写的:

for i, line in enumerate(csv, 1):
    alnum_words = sum(1 for word in line.split() if word.isalnum())
    line_details.append("Line %d has %d Alphanumeric word/s" % (i, alnum_words))

【讨论】:

  • 这不计算以句点或逗号结尾的单词,因为它会将单词视为非字母数字。
  • 是的。问题是这是否是OP想要的。 OTOH,如果不是,那么“非字母数字词”是什么?例如,xxx-yyy 是非字母数字词还是用标点符号分隔的两个词?
【解决方案2】:

正则表达式可能是最好的方法。但无论如何……

这不是正则表达式解决方案

此实现假定字母数字 set 中的任何字符或字符序列都计为一个单词。因此,例如,它会计算代码块中的标识符名称等内容。

由任何非字母数字字符分隔的单词单独计算;例如空格、制表符、分号和斜杠。如果您想将带有撇号或连字符的单词计为一个,请将它们添加到 chars 的集合中。

>>> chars = set('abcdefghijklmnopqrstuvwxyz'
...             'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
...             '0123456789'
...             '_')     # Underscores to match identifiers?
...             # "-'")    Are these separators or parts of a word?
...
>>> def count_alphanum_words(s):
...     w = False
...     count = 0
...     for ch in s:
...         if ch in chars:
...             w = True
...         else:
...             if w:
...                 count += 1
...                 w = False
...     if w:
...         count += 1
...     return count
...     
>>> count_alphanum_words("Th3 qu1ck 8r0wn f0x jump3d 0v3r th3 l4zy d0g.")
9
>>> line_details = []
>>> for n, line in enumerate(csv, 1):
...     count = count_alphanum_words(line)
...     line_details.append("Line %d has %d Alphanumeric words" % (n, count))
...
>>> for line in line_details:
...     print(line)

该算法应该很快,因为它只需要遍历一行中的字符即可获得字数。使用split() 的其他方法会导致一次传递进行拆分,然后再传递一次以处理它生成的项目列表,以及对单个单词的字符进行迭代以确定它们是否是字母数字。

但是,split()isalnum() 的解决方案在本机代码中执行更多操作。因此,此代码与其他解决方案的性能时间差异可以忽略不计。不过,其他解决方案可能无法正确计算单词。

【讨论】:

  • regex 本来是完美的解决方案,但问题是没有regex
  • 好吧...我会想出另一种方法并更新它。
  • 谢谢@Todd,这是一个非常好的解释,但尽可能不使用正则表达式。再次感谢您
  • 这个解决方案不使用正则表达式!! @Ajedrez 它使用一组。这不是正则表达式。
【解决方案3】:

这是你想要的吗?

line = "Rolls-Royce Motor Cars Inc. said it expects its U.S. sales to remain steady at about 1,200 cars in 1990"   
line_char =  sum(i.isalnum() for i in line.split())

print(line_char)

输出:15

【讨论】:

  • OP 想要计算字数,而不是字符数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2011-04-13
  • 2018-11-26
  • 1970-01-01
相关资源
最近更新 更多