You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python正则捕获含缩写的重叠双词序列?及模式调整方案

嘿,很高兴帮你解决这两个正则相关的问题!

问题1:编写可捕获含缩写重叠双词序列的Python正则表达式

要捕获文本中包含缩写(比如can't、won't这类带撇号的形式)的重叠双词序列,关键要解决两个核心点:一是正确定义能识别缩写的“词”,二是实现重叠匹配(也就是滑动窗口式的连续双词,比如one can't之后紧接着匹配can't two)。

这里给出一个实用的正则方案:

import re

text = "one can't two won't three"
# 正则逻辑拆解:
# - (?=...) 正向预查:不消耗字符,实现重叠匹配的核心
# - (?:^|(?<=\s)) 确保词的开头是字符串起始或空白,避免从词内部开始匹配
# - [\w\'’-]+ 匹配包含字母、撇号、连字符的词,覆盖缩写和带连字符的词
# - (?:(?=\s)|(?=$)) 确保词的结尾是空白或字符串结束,避免匹配词的一部分
pattern = r'(?=((?:^|(?<=\s))[\w\'’-]+ [\w\'’-]+(?:(?=\s)|(?=$))))'
matches = re.findall(pattern, text)
print(matches)
# 输出: ["one can't", "can't two", "two won't", "won't three"]

核心思路:

  • 用正向预查(?=...)实现重叠:普通正则匹配会消耗字符,导致无法捕获重叠的序列,而预查只是检查后续内容是否符合,不会移动匹配指针,所以能逐个位置滑动检查。
  • 自定义词的边界:用(?:^|(?<=\s))和(?:(?=\s)|(?=$))替代原生的\b,避免\b在缩写内部(比如can't里的'和t之间)误触发匹配。
  • 词的匹配范围:[\w\'’-]+覆盖了常见的缩写(带撇号)、普通单词,以及带连字符的词(比如mother-in-law)。

问题2:调整现有正则以得到期望输出

先分析你给出的代码问题:原正则里的\b(单词边界)是导致错误输出的根源。因为\b的定义是\w(字母/数字/下划线)和非\w字符的边界,而缩写里的'属于非\w,所以can't内部会出现两个\b(n和'之间、'和t之间)。这导致正则会在'后面的位置尝试匹配,把t当成一个独立的词,从而出现t two、t three这类错误结果。

调整后的正则方案

只需要把原生的\b替换为基于空白/字符串首尾的自定义边界,就能避免内部误匹配:

from re import findall
s= '''one can't two won't three'''
# 调整后的正则:用空白/首尾限定词的边界,避免内部误匹配
pat = r'(?=((?:(?<=^)|(?<=\s))[\w\'’-]+ [\w\'’-]+(?:(?=\s)|(?=$))))'
s2 = findall(pat, s)
print(s2)
# 期望输出: ["one can't", "can't two", "two won't", "won't three"]

调整细节解释:

  • (?:(?<=^)|(?<=\s)):确保当前位置的前一个字符是字符串开头或者空白,这样就不会从can't里的'后面开始匹配(因为'不是空白)。
  • (?:(?=\s)|(?=$)):确保当前位置的后一个字符是空白或者字符串结尾,避免把词的一部分当成完整词。
  • 保留[\w\'’-]+:确保能正确匹配带撇号、连字符的缩写和单词。

内容的提问来源于stack exchange,提问作者Nicholas Nickleby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:41:58