奇数个还是偶数个反斜杠和转义字符

3
我对以下代码有一点小问题。
import re

pattern = re.compile(r"((?:^|[^\\@]|\\.)+)@")

for text in [
    r"ok@\@.py",
    r"ok@\\@.py",
    r"ok@\\\@.py",
    r"ok@\\\\@.py",
    r"ok@\\\\\@.py",
]:
    search = re.search(pattern, text)
    print('---', text, sep="\n")

    if search:
        print(pattern.sub(r"\1<star>", text))

    else:
        print('<< NOTHING FOUND ! >>')

这将打印:

---
ok@\@.py
ok<star>\@.py
---
ok@\\@.py
ok<star>\\<star>.py
---
ok@\\\@.py
ok<star>\\\<star>.py
---
ok@\\\\@.py
ok<star>\\\\<star>.py
---
ok@\\\\\@.py
ok<star>\\\\\<star>.py

问题始于第三个输出,因为首先有一个转义的反斜杠,然后是转义字符@。问题继续出现更多反斜杠:只需查看最后一个输出,其中有两个转义的反斜杠,然后是转义字符@。
以下是预期输出,当@前面有奇数个反斜杠时才进行转义。
---
ok@\@.py
ok<star>\@.py
---
ok@\\@.py
ok<star>\\<star>.py
---
ok@\\\@.py
ok<star>\\\@.py
---
ok@\\\\@.py
ok<star>\\\\<star>.py
---
ok@\\\\\@.py
ok<star>\\\\\@.py

我的正则表达式有什么问题,怎样才能修复它?

3
你还没有告诉我们期望的行为。如果我们不知道它应该做什么,我们要如何修复它呢? - Karoly Horvath
@KarolyHorvath,我已经更新了我的问题。 - projetmbc
1个回答

2
使用以下正则表达式:
pattern = re.compile(r"(?<!\\)((?:\\\\)*)@")

并替换为只有<star>

输出:

ok<star>\@.py 
ok<star>\\<star>.py
ok<star>\\\@.py
ok<star>\\\\<star>.py
ok<star>\\\\\@.py

查看 DEMO


实际上,输出结果会根据反斜杠的数量是偶数还是奇数而发生变化。 - projetmbc
我已经更新了我的问题,第一次说得不是很清楚,只有在@前面有奇数个\时才会转义。 - projetmbc
很酷!但是 pattern = re.compile(r"(?<!\\)((?:\\\\)*)@") 怎么办? - projetmbc
1
是的,那是多余的,已经删除了。 :) - karthik manchala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接