regex 具有相同图案结构的分割(!)|(!\?)和(!)|(e!)但在python正则表达式中的行为不同

3hvapo4f  于 2023-06-25  发布在  Python
关注(0)|答案(2)|浏览(67)

我想拆分的句子是这样的。
sentence = "Break!me!?haha"
第一个模式是
pattern = r'(!)|(!\?)'
这些代码的结果是

print(re.split(pattern,sentence))
print([word for word in re.split(pattern, sentence) if word != None and not word == ""])
['Break', '!', None, 'me', '!', None, '?haha']
['Break', '!', 'me', '!', '?haha']

!?用作分隔符。而不是!!?
但当我用这个句型时
pattern = r'(!)|(e!)'
以上代码相同结果为

['Break', '!', None, 'm', None, 'e!', '?haha']
['Break', '!', 'm', 'e!', '?haha']

这次的分隔符是!e!
但我认为这些模式使用相同的结构。

pattern = r'(!)|(!\?)'
pattern = r'(!)|(e!)'

下面是工作代码
https://www.online-python.com/UrgFEQVCvR

yebdmbv4

yebdmbv41#

对于模式pattern = r'(!)|(!\?)',regex处理模式的方式使得它只会在(!\?)不匹配(!)时尝试匹配(!\?)。显然,如果它不匹配(!),它将永远不会匹配(!\?)。将语句翻转过来:

sentence = "Break!me!?haha"
pattern = r'(!\?)|(!)'

import re

print(re.split(pattern,sentence))
print([word for word in re.split(pattern, sentence) if word != None and not word == ""])

#output
['Break', None, '!', 'me', '!?', None, 'haha']
['Break', '!', 'me', '!?', 'haha']

对于第二个模式pattern = r'(!)|(e!)',您可能无法匹配(!),但可以匹配(e!),这正是所发生的情况。

w8biq8rn

w8biq8rn2#

模式的结构不同-在第一个模式中,两个备选项共享相同的起始字符,因此第一个备选项((!))将首先匹配,而在第二个模式中,它们不匹配,因此第二个备选项首先匹配(因为e!可以在!之前匹配)。
如果你想让(!\?)优先于(!),你需要把它放在第一位:

pattern = r'(!\?)|(!)'

(虽然你可以简单地使用

pattern = r'(!\??)'

而是因为?是贪婪的)。

相关问题