正则表达式在 Python 中拆分单词

Posted

技术标签:

【中文标题】正则表达式在 Python 中拆分单词【英文标题】:Regex to split words in Python 【发布时间】:2012-09-24 04:36:42 【问题描述】:

我正在设计一个正则表达式来拆分给定文本中的所有实际单词

输入示例:

"John's mom went there, but he wasn't there. So she said: 'Where are you'"

预期输出:

["John's", "mom", "went", "there", "but", "he", "wasn't", "there", "So", "she", "said", "Where", "are", "you"]

我想到了这样的正则表达式:

"(([^a-zA-Z]+')|('[^a-zA-Z]+))|([^a-zA-Z']+)"

在 Python 中拆分后,结果包含None 项和空格。

如何去掉 None 项?为什么空格不匹配?

编辑: 在空格上拆分,将给出如下项目:["there."] 并且拆分非字母,将给出如下项目:["John","s"] 除了' 之外的非字母拆分,将给出如下项目:["'Where","you'"]

【问题讨论】:

为什么必须是split 而不是findall 在这里定义要匹配的内容要简单得多:findallr"[a-zA-Z]+(?:'[a-z])?" 可以完成这项工作。所以我真的很好奇想要split的原因。 另一个错误修复更新。现在它可以捕获单个字母,在开头或结尾加上撇号。 @ChrisWesseling 是的,我认为这更容易,谢谢! 【参考方案1】:

您可以使用字符串函数来代替正则表达式:

to_be_removed = ".,:!" # all characters to be removed
s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!'"

for c in to_be_removed:
    s = s.replace(c, '')
s.split()

但是,在您的示例中,您不想删除 John's 中的撇号,但您希望删除 you!!' 中的撇号。所以字符串操作在那个时候失败了,你需要一个微调的正则表达式。

编辑:可能一个简单的正则表达式可以解决您的问题:

(\w[\w']*)

它将捕获所有以字母开头的字符并继续捕获,而下一个字符是撇号或字母。

(\w[\w']*\w)

第二个正则表达式是针对一个非常特殊的情况......第一个正则表达式可以捕获像you' 这样的词。这将避免这种情况,并且仅在 is 在单词内(不在开头或结尾)时才捕获撇号。但是在那一点上,出现了一种情况,您无法使用第二个正则表达式捕获撇号Moss' mom。您必须决定是否在以 s 结尾的名称中捕获尾随撇号并定义所有权。

例子:

rgx = re.compile("([\w][\w']*\w)")
s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!'"
rgx.findall(s)

["John's", 'mom', 'went', 'there', 'but', 'he', "wasn't", 'there', 'So', 'she', 'said', 'Where', 'are', 'you']

更新 2:我在我的正则表达式中发现了一个错误!它不能捕获单个字母后跟像A' 这样的撇号。修复了全新的正则表达式:

(\w[\w']*\w|\w)

rgx = re.compile("(\w[\w']*\w|\w)")
s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!' 'A a'"
rgx.findall(s)

["John's", 'mom', 'went', 'there', 'but', 'he', "wasn't", 'there', 'So', 'she', 'said', 'Where', 'are', 'you', 'A', 'a']

【讨论】:

a.findall(s) 不起作用,因为没有定义 a。相反,该行应该是re.findall(rgx,s) Opss,我忘记更改变量名了。谢谢,错误已修复。 另外,我注意到最后的正则表达式遗漏了像 'a' 等单字母单词。 因为正则表达式是 (\w[\w']*\w|\w) 但我忘记在最后一个示例中替换它。固定 @meyer1994 是的,我的测试证实正则表达式也可以处理多行文本。【参考方案2】:

你的正则表达式中有太多的捕获组;使它们不被捕获:

(?:(?:[^a-zA-Z]+')|(?:'[^a-zA-Z]+))|(?:[^a-zA-Z']+)

演示:

>>> import re
>>> s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!'"
>>> re.split("(?:(?:[^a-zA-Z]+')|(?:'[^a-zA-Z]+))|(?:[^a-zA-Z']+)", s)
["John's", 'mom', 'went', 'there', 'but', 'he', "wasn't", 'there', 'So', 'she', 'said', 'Where', 'are', 'you', '']

只返回 一个 为空的元素。

【讨论】:

我之前想过那个简化版,但是问题是“她说'go'”会导致[ ....,“'go'”],这是不正确的 @Betamoo:是的,正在调整,因为我看到你的表达方式到目前为止(错过了一个括号)。 @VishalSuthar:抱歉,您的编辑很垃圾。 “non-capturing”是普通词,不是需要渲染为代码的东西。 我刚刚遇到了一个完全不同的问题,但将? 更改为?:也解决了它!谢谢【参考方案3】:

这个正则表达式只允许一个结束撇号,后面可以再跟一个字符:

([\w][\w]*'?\w?)

演示:

>>> import re
>>> s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!' 'A a'"
>>> re.compile("([\w][\w]*'?\w?)").findall(s)
["John's", 'mom', 'went', 'there', 'but', 'he', "wasn't", 'there', 'So', 'she', 'said', 'Where', 'are', 'you', 'A', "a'"]

【讨论】:

【参考方案4】:

我是 python 新手,但我想我已经弄明白了

import re
s = "John's mom went there, but he wasn't there. So she said: 'Where are you!!'"
result = re.findall(r"(.+?)[\s'\",!]1,", s)
print(result)

结果 ['John', 's', 'mom', 'went', 'there', 'but', 'he', 'wasn', 't', 'there.', 'So', 'she', '说:','在哪里','在','你']

【讨论】:

您的答案将John's 拆分为Johns,并保留said: 中的:。感谢您尝试做出贡献,但这个问题已经有答案可以完全完成所要求的内容,请考虑帮助解决其他尚无理想答案的问题。不过,感谢您尝试做出贡献。

以上是关于正则表达式在 Python 中拆分单词的主要内容,如果未能解决你的问题,请参考以下文章

基于正则表达式拆分字符串

Java - 正则表达式拆分输入文本但保留分隔符[重复]

使用php preg_match(正则表达式)将camelCase单词拆分为单词

正则表达式标点分割[Python]

如何使用正则表达式拆分字符串并包含空格

Java 和 C# 正则表达式不产生相同的结果