首页 > 解决方案 > 为什么我的正则表达式中的 $ 不匹配行尾

问题描述

我有以下测试程序:

import re

class Test:
    def __init__ (self):
        self.idFiltering = True
        self.aliases = [
            ('rose', 'jasmin')
        ]

        for s in (
            '__rose__',
            'rose',

            'moon__rose',
            'rose__fish',
            'moon__rose__jelly__fish',
            'moon__rose__rose__rose__fish',

            'sun.moon.rose',
            'rose.fish',
            'rosexfish',
            'moon.rose.jelly__fish',

            'moon/rose',
            'rose/fish',
            'moon/rose/jelly__fish',

        ):   
            print (s, self.filterId (s))
        print ('done')

    def filterId (self, qualifiedId):
        if not self.idFiltering or (qualifiedId.startswith ('__') and qualifiedId.endswith ('__')):
            return qualifiedId
        else:        
            for alias in self.aliases:
                pattern = re.compile (rf'((__)|(?=[^./])){alias [0]}((__)|(?=[./$]))')

                # Replace twice to deal with overlap
                qualifiedId = pattern.sub (alias [1], qualifiedId)
                qualifiedId = pattern.sub (alias [1], qualifiedId)

            return qualifiedId

test = Test ()

我希望它产生:

__rose__ __rose__
rose jasmin
moon__rose moon__jasmin
rose__fish jasminfish
moon__rose__jelly__fish moonjasminjelly__fish
moon__rose__rose__rose__fish moonjasminjasminjasminfish
sun.moon.rose sun.moon.jasmin
rose.fish jasmin.fish
rosexfish rosexfish
moon.rose.jelly__fish moon.jasmin.jelly__fish
moon/rose moon/jasmin
rose/fish jasmin/fish
moon/rose/jelly__fish moon/jasmin/jelly__fish
done

但它产生:

__rose__ __rose__
rose rose
moon__rose moon__rose
rose__fish jasminfish
moon__rose__jelly__fish moonjasminjelly__fish
moon__rose__rose__rose__fish moonjasminjasminjasminfish
sun.moon.rose sun.moon.rose
rose.fish jasmin.fish
rosexfish rosexfish
moon.rose.jelly__fish moon.jasmin.jelly__fish
moon/rose moon/rose
rose/fish jasmin/fish
moon/rose/jelly__fish moon/jasmin/jelly__fish
done

换句话说,它不会替换单词末尾的“rose”。它似乎忽略了我模式中的 $ 。我究竟做错了什么?

[在 Aran-Fey 和 Pushpesh Kumar Rajwanshi 评论后编辑]

我已将正则表达式更改为:

rf'((__)|(?=[^./])){alias [0]}((__)|(?=[./])|$)'

现在它工作正常,所以我的问题解决了。

我也试过:

rf'(^|(__)|(?=[./])){alias [0]}((__)|(?=[./])|$)'

但这不起作用。只是好奇:为什么不呢?

[编辑2]

正如 Rarblack 指出的那样,我的解决方案完全靠运气。根据他/她的建议,我认为我找到了正确的正则表达式:

rf'(^|(__)|(?<=[./])){alias [0]}((__)|(?=[./])|$)'

它产生了预期的输出,这一次并非巧合。

标签: pythonregex

解决方案


当您将特殊的正则表达式属性放入其中时,[]它们会失去意义并像普通字符一样行事。这就是为什么[./$]不工作。此外,放在^方括号内意味着不过滤其中的所有属性:[^./].


推荐阅读