Python 缩写和标点符号的正则表达式模式

Python 缩写和标点符号的正则表达式模式,python,regex,nltk,Python,Regex,Nltk,我有一个段落,我想通过将标点符号与单词分开来标记它,并打印结果。有些特殊情况下,缩写词如U.S.A和撇号如Peter'S,小数应附在字母后面,而不是分开 我运行以下代码: import re text = "My weight is about 68 kg, +/- 10 grams! I live in U.S.A. at Mr. Peter's house! 3,500 calorie rule, which equates a weight alteration of 2.2 lb

我有一个段落,我想通过将标点符号与单词分开来标记它,并打印结果。有些特殊情况下,缩写词如U.S.A和撇号如Peter'S,小数应附在字母后面,而不是分开

我运行以下代码:

import re

text = "My weight is about 68 kg, +/- 10 grams! I live in U.S.A. at Mr. 
Peter's house!  3,500 calorie rule, which equates a weight alteration 
of 2.2 lb"

pattern = r"""(?:[A-Z]\.)+ |\d+(?:\.\d+)?%?|\w/.+$\s-|\w+(?:[-']\w+)*|
(?:[+/\-@&*]|/.$/)"""

print (re.findall(pattern, text))
输出:

['My', 'weight', 'is', 'about', '68', 'kg', '+', '/', '-', '10', 
 'grams', 'I', 'live', 'in', 'U.S.A. ', 'at', 'Mr', "Peter's", 'house',
 '3', '500', 'calorie', 'rule', 'which', 'equates', 'a', 'weight',
 'alteration', 'of', '2.2', 'lb'
]
这段代码有一些错误,我真的需要帮助来修复它们:

它删除了所有的标点符号!我想保留它们,但要与文字分开

模式忽略包含的数字,并将其删除。我添加了\d+?:\,\d+?%?但它不能正常工作

该模式还忽略了一些缩写,例如Mr


非常感谢您的帮助

我建议您避免使用正则表达式执行此操作,而应使用专门为此任务设计的工具。以下内容应涉及美国和Peter的:

这将为您提供以下可能性:

['My', 'weight', 'is', 'about', '68', 'kg,', '+/-', '10', 'grams!', 'I', 'live', 'in', 'U.S.A.', 'at', 'Mr.', "Peter's", 'house!', '3,500', 'calorie', 'rule,', 'which', 'equates', 'a', 'weight', 'alteration', 'of', '2.2', 'lb']
['My', 'weight', 'is', 'about', '68', 'kg', ',', '+/-', '10', 'grams', '!', 'I', 'live', 'in', 'U.S.A.', 'at', 'Mr.', 'Peter', "'s", 'house', '!', '3,500', 'calorie', 'rule', ',', 'which', 'equates', 'a', 'weight', 'alteration', 'of', '2.2', 'lb']

如果您不打算使用成熟的自然语言处理工具,我建议您使用更简单的模式,并计划进行一些解析后清理。试图解决模式匹配中的所有问题是很棘手的,并且随着新语法元素的引入,可能会继续失败。也就是说,这里有一个更简单的模式方法,我相信它可以处理与您有关的大多数异常:

import re

text = "My weight is about 68 kg, +/- 10 grams! I live in U.S.A. at Mr. Peter's house!  3,500 calorie rule, which equates a weight alteration of 2.2 lb"

pattern = r"(\s+|(?:[A-Z']\.?)+)"

tokens = [token for token in re.split(pattern, text, flags=re.I) if token and not token.isspace()]

print(tokens)
输出

['My', 'weight', 'is', 'about', '68', 'kg', ',', '+/-', '10', 'grams',
'!', 'I', 'live', 'in', 'U.S.A.', 'at', 'Mr.', "Peter's", 'house', '!',
'3,500', 'calorie', 'rule', ',', 'which', 'equates', 'a', 'weight',
'alteration', 'of', '2.2', 'lb']

我不是使用re.findall,而是使用re.split和模式保留来隔离字符串中的标记,也就是说,我们在单词上进行分割。当出现新的异常时,请评估是否值得使模式复杂化,或者是否可以在解析之前或之后处理它们。

我认为这不是完全可能的。正则表达式如何知道U.S.a.的最后一点是否是句子的结尾?好的,我肯定会使用这个工具,但是输出中有一个错误。“grams!”中的标点符号还有“房子!”应该从这个词中删去。所以,正确的输出应该是‘克’,‘克!’,'房子','!'在这种情况下,我可以将正则表达式与此代码一起使用吗?您还可以研究word_标记化作为替代方法。我已经更新了脚本。谢谢你的更新。第二个输出中的问题是,名称Peter’s中的撇号是分开的,不应该分开彼得:“我将此添加到代码中以修复撇号,但它不起作用。pattern=r?:[^\W\d\u]?:[^\W\d\u]|['\-]+[^\W\d]nltk.regexp\u tokenizetext,pattern非常感谢您的代码。它可以很好地作为我想要的输出。我想知道如果我想使用nltk.tokenize怎么办。我也应该使用正则表达式吗?或者,代码将非常简单。我将nltk和python 3与您的模式regexp_tokenizetext一起使用,模式=\s++:[A-Z']\.?+,但它向我展示了以下内容:['M','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','',']@BeautifulMind,正如我在解释中指出的,我的模式是为re.split设计的,它应用的模式不同于其他正则表达式函数,然后理解删除空字符串和空白。regexp_tokenize函数以不同的方式应用模式,这是非常感谢您的回答!我真的很感激。
['My', 'weight', 'is', 'about', '68', 'kg', ',', '+/-', '10', 'grams',
'!', 'I', 'live', 'in', 'U.S.A.', 'at', 'Mr.', "Peter's", 'house', '!',
'3,500', 'calorie', 'rule', ',', 'which', 'equates', 'a', 'weight',
'alteration', 'of', '2.2', 'lb']