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

Python正则表达式:如何仅捕获精确匹配,排除#apple中的apple

问题:正则匹配时避免同时捕获带#的标签及其中的单词

以下是当前使用的代码:

import re
fruit_list = ['apple banana', 'apple', 'pineapple', 'banana', 'banana apple',  'kiwi']
fruit = re.compile('|'.join(fruit_list))
fruit_re = [ re.compile(r'\b('+re.escape(fruit)+r')\b') for fruit in fruit_list]
fruit_re.append(re.compile( r'([#@])(\w+)'))

string = "this is pooapple is banana apple #apple"

for ft in fruit_re:
    
    match = re.finditer(ft, string)  
    print(type(match))
    for mat in match:
        
        print(mat.span())
        print(mat.group())
        print("****************")

当前代码的问题是:会同时捕获#apple(位置33,39)以及其中的apple(位置34,39),运行输出如下:

(27, 32)
apple
****************
(34, 39)
apple
****************
<class 'callable_iterator'>
<class 'callable_iterator'>
(20, 26)
banana
****************
<class 'callable_iterator'>
(20, 32)
banana apple
****************
<class 'callable_iterator'>
<class 'callable_iterator'>
(33, 39)
#apple
****************

需求是仅捕获#apple,不捕获其中的apple,该如何实现?


解决方案

核心思路是让匹配水果单词的正则排除掉紧跟在#或@后面的单词,通过添加负向零宽断言即可实现:

修改生成fruit_re的正则表达式,在单词边界前加入(?<![#@]),确保匹配的单词前面不是#或@符号:

import re
fruit_list = ['apple banana', 'apple', 'pineapple', 'banana', 'banana apple',  'kiwi']
# 新增负向后行断言,排除#/@后的单词匹配
fruit_re = [ re.compile(r'(?<![#@])\b('+re.escape(fruit)+r')\b') for fruit in fruit_list]
fruit_re.append(re.compile( r'([#@])(\w+)'))

string = "this is pooapple is banana apple #apple"

for ft in fruit_re:
    match = re.finditer(ft, string)  
    print(type(match))
    for mat in match:
        print(mat.span())
        print(mat.group())
        print("****************")

修改后的运行输出将不再包含#apple中的apple匹配项,只会保留正常的水果单词和完整的标签匹配结果。

原理说明

(?<![#@])是负向后行断言,表示当前位置的前一个字符不能是#或@。当正则尝试匹配#apple里的apple时,因为apple前面是#,不满足断言条件,就会被自动排除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:42:32