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

如何使用\b单词边界构建正则,使点号不成为匹配分隔符?

正则匹配需求:拆分单词与非单词字符串,保留域名整体

给定字符串:

s = "Hi, domain: (foo.bar.com) bye"

期望使用re.findall()得到如下结果:

# 返回: ["Hi", ", ", "domain", ": (", "foo.bar.com", ") ", "bye"]

要求分别提取单词和连续的非单词字符串,但需将foo.bar.com这类带点的域名视为整体,不能拆分,且不能以空格作为分隔条件。

初始尝试使用单词边界\b编写正则:

regex = r'(?:^|\b).*?(?=\b|$)'
re.findall(regex, s)
# 返回: ["Hi", ",", "domain", ": (", "foo", ".", "bar", ".", "com", ") ", "bye"]

问题在于\b会把点号当作单词边界,导致域名被拆分成多个片段。


解决方案

方案一:直接匹配两种目标模式

通过明确写出“含点域名类单词”和“非单词字符序列”两种规则,让正则引擎优先匹配符合要求的内容:

import re

s = "Hi, domain: (foo.bar.com) bye"
regex = r'\w+(?:\.\w+)*|\W+'
result = re.findall(regex, s)
print(result)
# 输出: ['Hi', ', ', 'domain', ': (', 'foo.bar.com', ') ', 'bye']
  • \w+(?:\.\w+)*:匹配由点号连接的单词序列,比如foo.bar.com。其中(?:\.\w+)*是非捕获组,用来匹配零个或多个“点+单词”的组合,避免生成多余的分组结果。
  • \W+:匹配一个或多个连续的非单词字符,对应需要单独提取的非单词部分。

方案二:自定义边界断言

如果需要更灵活的边界控制,可以用断言来定义不会拆分域名的自定义边界:

import re

s = "Hi, domain: (foo.bar.com) bye"
regex = r'(?:^|(?<![\w.]))(?:[\w.]+|\W+)(?![\w.])'
result = re.findall(regex, s)
print(result)
# 输出同样符合预期
  • (?<![\w.]):负向回顾后发断言,确保当前位置的前一个字符不是单词字符或点号,以此作为自定义的“非目标单词”边界。
  • [\w.]+:匹配包含点号的域名类字符串。
  • \W+:匹配连续的非单词字符序列。
  • (?![\w.]):负向前瞻断言,确保当前位置的后一个字符不是单词字符或点号,完成边界的界定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:30:55