嗨,我有一个关于将字符串拆分为标记的问题。
这是一个示例字符串:
string
=“当我在等待时,一个人从一间侧室出来,一眼就能确定他一定是长约翰。他的左腿被臀部割断,在下面他的左肩carried着拐杖,非常灵巧地管理着它,像只鸟一样在它上面跳来跳去。他高大而强壮,脸像火腿一样大,脸色苍白,苍白,但聪明而微笑。他似乎洋溢着最开朗的精神,在桌子间四处走动时吹口哨,用快乐的话语或一巴掌打招呼,以迎接客人的青睐。”
,并且我正在尝试将string
正确地分成其令牌。
这是我的功能count_words
def count_words(text):
"""Count how many times each unique word occurs in text."""
counts = dict() # dictionary of { <word>: <count> } pairs to return
#counts["I"] = 1
print(text)
# TODO: Convert to lowercase
lowerText = text.lower()
# TODO: Split text into tokens (words), leaving out punctuation
# (Hint: Use regex to split on non-alphanumeric characters)
split = re.split("[\s.,!?:;'\"-]+",lowerText)
print(split)
# TODO: Aggregate word counts using a dictionary
和split
的结果
['as','i','was','waiting','a','man','came','out','of','a', “侧面”,“房间”,“和”,“在”,“一个”,“扫视”,“我”,“是”,“确定”,“他”, “必须”,“是”,“长”,“约翰”,“他”,“左”,“腿”,“是”,“切”, “关闭”,“关闭”,“通过”,“该”,“臀部”,“和”,“下方”,“该”,“左侧”, “肩膀”,“他”,“携带”,“一个”,“拐杖”,“其中”,“他”,“受管理”, “有”,“精彩”,“灵巧”,“跳跃”,“关于”,“在”,“它”, “喜欢”,“一只”,“鸟”,“他”,“是”,“非常”,“高”,“和”,“强壮”, “ with”,“ a”,“ face”,“ as”,“ big”,“ as”,“ a”,“ ham-plain”,“ and”, “苍白”,“但是”,“智能”,“和”,“微笑”,“确实”,“他”, “似乎”,“中”,“该”,“最”,“开朗”,“精神”,“低语”, “是”,“他”,“移动”,“大约”,“中间”,“该”,“桌子”,“带有”,“一个”, “快乐”,“单词”,“或”,“一个”,“巴掌”,“上”,“该”,“肩膀”,“用于”, 'the','more','favoured','of','his','guests','']
如您所见,''
列表的最后一个索引中有一个空字符串split
。
请帮助我理解列表中的空字符串,并正确分割此示例string
。
答案 0 :(得分:3)
您可以使用list comprehension遍历re.split
产生的列表项,并仅在它们不是空字符串时保留它们:
def count_words(text):
"""Count how many times each unique word occurs in text."""
counts = dict() # dictionary of { <word>: <count> } pairs to return
#counts["I"] = 1
print(text)
# TODO: Convert to lowercase
lowerText = text.lower()
# TODO: Split text into tokens (words), leaving out punctuation
# (Hint: Use regex to split on non-alphanumeric characters)
split = re.split("[\s.,!?:;'\"-]+",lowerText)
split = [x for x in split if x != ''] # <- list comprehension
print(split)
您还应该考虑从函数返回数据,并从调用方打印数据,而不是从函数内部打印数据。这将为您将来提供灵活性。
答案 1 :(得分:2)
发生这种情况是因为字符串的末尾是.
,并且它在拆分pattern
中,所以,当匹配.
时,下一个匹配将以空开头,这就是为什么看到{ {1}}。
我建议使用''
这种解决方案,而不是像这样使用相反的方式:
re.findall
答案 2 :(得分:1)
Python的wiki解释了此行为:
如果分隔符中有捕获组,并且在 字符串开头,结果将以空字符串开头。的 字符串的末尾也是如此
即使您实际上不是捕获组,其效果也相同。请注意,它可以在结尾也可以在开头(例如,如果您的字符串以空格开头)。
其他人已经(或多或少)提出的2个解决方案是这些:
findall
正如其他用户指出的那样,您可以使用findall
并尝试逆转模式的逻辑。对于您的角色,您可以轻松取消自己的角色类别:[^\s\.,!?:;'\"-]+
。
但这取决于您的正则表达式模式,因为它并不总是那么容易。
您不必检查每个标记是否为!= ''
,而只需查看标记中的第一个或最后一个标记,因为您急切地使用了集合中的所有字符您需要继续前进。
split = re.split("[\s\.,!?:;'\"-]+",lowerText)
if split[0] == '':
split = split[1:]
if split[-1] == '':
split = split[:-1]
答案 3 :(得分:1)
您有一个空字符串,这是因为一个点也匹配要在string
结尾处拆分,并且任何内容都在下游。但是,您可以使用filter
函数过滤掉空字符串,从而完成函数:
import re
import collections
def count_words(text):
"""Count how many times each unique word occurs in text."""
lowerText = text.lower()
split = re.split("[ .,!?:;'\"\-]+",lowerText)
## filer out empty strings and count
## words:
return collections.Counter( filter(None, split) )
count_words(text=string)
# Counter({'a': 9, 'he': 6, 'the': 6, 'and': 5, 'as': 4, 'was': 4, 'with': 3, 'his': 2, 'about': 2, 'i': 2, 'of': 2, 'shoulder': 2, 'left': 2, 'dexterity': 1, 'seemed': 1, 'managed': 1, 'among': 1, 'indeed': 1, 'favoured': 1, 'moved': 1, 'it': 1, 'slap': 1, 'cheerful': 1, 'at': 1, 'in': 1, 'close': 1, 'glance': 1, 'face': 1, 'pale': 1, 'smiling': 1, 'out': 1, 'tables': 1, 'cut': 1, 'ham': 1, 'for': 1, 'long': 1, 'intelligent': 1, 'waiting': 1, 'wonderful': 1, 'which': 1, 'under': 1, 'must': 1, 'bird': 1, 'guests': 1, 'more': 1, 'hip': 1, 'be': 1, 'sure': 1, 'leg': 1, 'very': 1, 'big': 1, 'spirits': 1, 'upon': 1, 'but': 1, 'like': 1, 'most': 1, 'carried': 1, 'whistling': 1, 'merry': 1, 'tall': 1, 'word': 1, 'strong': 1, 'by': 1, 'on': 1, 'john': 1, 'off': 1, 'room': 1, 'hopping': 1, 'or': 1, 'crutch': 1, 'man': 1, 'plain': 1, 'side': 1, 'came': 1})
答案 4 :(得分:0)
import string
def count_words(text):
counts = dict()
text = text.translate(text.maketrans('', '', string.punctuation))
text = text.lower()
words = text.split()
print(words)
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
return counts
有效。