【发布时间】:2020-01-18 21:09:52
【问题描述】:
我正在尝试在标点符号之后匹配空格,以便拆分大量文本,但我看到一些常见的边缘情况,包括地点、标题和常见的缩写:
I am from New York, N.Y. and I would like to say hello! How are you today? I am well. I owe you $6. 00 because you bought me a No. 3 burger. -Sgt. Smith
我在 Python 3 中将它与 re.split 函数一起使用我想得到这个:
["I am from New York, N.Y. and I would like to say hello!",
"How are you today?",
"I am well.",
"I owe you $6. 00 because you bought me a No. 3 burger."
"-Sgt. Smith"]
这是我目前的正则表达式:
(?<=[\.\?\!])(?<=[^A-Z].)(?<=[^0-9].)(?<=[^N]..)(?<=[^o].)
我决定先尝试修复No.,使用最后两个条件。但它依赖于独立匹配N 和o,我认为这会在其他地方出现误报。我不知道如何让它只在句号后面生成字符串No。然后,我将对Sgt. 和我遇到的任何其他“问题”字符串使用类似的方法。
我正在尝试使用类似的东西:
(?<=[\.\?\!])(?<=[^A-Z].)(?<=[^0-9].)^(?<=^No$)
但是在那之后它没有捕获任何东西。我怎样才能让它排除某些我希望在其中有句点的字符串,而不是捕获它们?
这是我的情况的正则表达式:https://regexr.com/4sgcb
【问题讨论】:
-
您是否尝试过嵌套一些环视?例如
(?<=(?<!No)[\.\?\!])(有一个尾随空格)匹配标点符号前面的 1 个空格,只要后者前面没有No。但是我不知道 Python 的正则表达式,所以我不知道如何克服 lookbehind 断言必须是固定宽度的限制,例如,这会导致(?<=(?<!(No|Sgt))[\.\?\!])错误。跨度> -
这可能有很多边缘情况,但是对于您的示例数据,您可以尝试
(?<=[.?!](?! [a-z0-9]))(?<!-Sgt\.)请参阅regex101.com/r/RMn6dY/1 或者如果您可以使用正则表达式 PyPi 模块,您可以使用(?<=[.?!](?! [a-z0-9]))(?<![^\w\s]\S*\.)@ 987654323@ -
@Thefourthbird,理论上
()和[]应该也足以成为处理边缘情况的工具。但是生成的正则表达式可能确实很长不可读(就像您尝试在数字区间中匹配数字时一样)。 -
你能把潜在的边缘情况缩小到一个固定的集合吗?因为如果不是,我怀疑您是否能够在没有误报或误报的情况下做到这一点。让我们接受“不”。例如。是的,在您给出的上下文中,指的是“数字”的简短形式,而不是句子的结尾。但是,“不。我是你父亲”或“我的答案是否定的”呢?没有上下文就不可能区分这些。对于“否”,仅检查后续数字可能就足够了,但对于其他数字可能不会。例如:“军士头衔通常缩写为 Sgt。”
-
当您可以使用 2 个简单的正则表达式(
[\.\?!]、(?:[A-Z]\.){2,}|No\.)一个循环和一个条件...
标签: regex python-3.x regex-lookarounds