规则模式“^ab | cd$”和^(ab | cd)$有什么区别?

2024-10-02 04:32:48 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的regex模式有什么区别?在

pattern1 = "^ab|cd$"
pattern2 = "^(ab|cd)$"
pattern3 = "^(ab)|(cd)$"

我试图编写一个正则表达式来匹配罗马数字格式(0~3999)。 我写了一个模式:

pattern = "^M{1,3}|(CM|C?D|D?C{1,3})|(X?L|XC|L?X{1,3})|(I?V|IX|V?I{1,3})$"

这个模式和“diii”或者XIIII或者类似的模式相匹配,但是我希望我的三个匹配。在

为什么会这样?在


Tags: ab格式模式cdcmregexpatternix
2条回答
r"^ab|cd$"

在开头匹配ab,在结尾匹配cd。请注意,这与出现在行中间或行尾的ab不匹配。同样地,这将不匹配出现在开头或中间的cd。在

^{pr2}$

匹配只包含abcd的整行。此外,字符串cd或{}被单个组捕获。在

r"^(ab)|(cd)$"

与第一个相同,但它将ab或{}分成两个独立的组。在

^ab|cd$表示

  1. 字符串的开头,后跟ab
  2. cd后跟字符串结尾。在

也就是说,ab123匹配,因为粗体部分匹配1,并且 123cd匹配,因为粗体部分匹配2。也就是说,|符号的优先级在所有符号中最低。在

.search一起使用时,它与s.startswith('ab') or s.endswith('cd')相同;但是 如果使用.match而不是.search,则模式必须在字符串的开头匹配,因此得到s.startswith('ab') or s == 'cd'。在

^(ab|cd)$表示

  • 字符串的开头,后跟ab或{},然后接字符串结尾
  • ab|cd匹配的任何内容都可以作为match.group(1)获得

^(ab)|(cd)$与第一个相同,只是如果ab匹配,它可用作match.group(1),同样地,cd如果匹配,匹配该部分的文本可用作match.group(2)。在

注意,(...)在正则表达式中有两个用途-它们将原子分组到一个原子中,并使匹配的文本在match对象中可用。如果您只需要分组,您应该使用(?:...),因为生成子匹配字符串的成本很高。在


至于您的罗马数字正则表达式的问题,您在上层错误地使用了|分支。在

^M{1,3}|(CM|C?D|D?C{1,3})|(X?L|XC|L?X{1,3})|(I?V|IX|V?I{1,3})$

如果与.match(与.search一起使用,2-4甚至没有绑定到字符串的开头),它代表

  1. 字符串的开头后跟M{1,3}以及其后的任何内容
  2. 字符串的开头后跟CM|C?D|D?C{1,3}以及其后的任何内容
  3. 字符串的开头后跟X?L|XC|L?X{1,3}以及其后的任何内容
  4. 字符串的开头后跟I?V|IX|V?I{1,3},然后是字符串的结尾。在

您不希望在主级别使用|,而是将这1-4中的每一个都作为可选的,使用?;而且您通常希望使用非捕获组((?: ))进行分组。因此我们得到:

^{pr2}$

但它仍然匹配空字符串。要使其不匹配空字符串,可以使用零宽度正前向查找来要求整个构造至少匹配1个(任意)字符。在

Python docs

(?=...) Matches if ... matches next, but doesn’t consume any of the string. This is called a lookahead assertion. For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.

因此,我们可以将它放在字符串锚定符^的开头之后,以确保整个字符串至少匹配^.(即,字符串的开头后跟1个字符):

^(?=.)(?:M{1,3})?(?:CM|C?D|D?C{1,3})?(?:X?L|XC|L?X{1,3})?(?:I?V|IX|V?I{1,3})?$

也就是说:

  • 字符串开头(^
  • 字符串结束前至少有1个字符((?=.)
  • M{1,3}(可选),后跟
  • CM|C?D|D?C{1,3}(可选),后跟
  • X?L|XC|L?X{1,3}(可选),后跟
  • I?V|IX|V?I{1,3}(可选),后跟
  • 字符串结尾$

这应该是你想要的。在

相关问题 更多 >

    热门问题