尽管我使用问号,但正则表达式匹配重复的部分

时间:2020-09-08 10:36:19

标签: python regex

我需要检查路径名是否正确,然后创建了一个正则表达式,如下所示:

^\/2\d{3}(\/2\d{3}-(0[1-9]|1[0-2])(\/[a-z ]+(\/(g|o)(\/[a-z ]+(\/s)?)?)?)?)?$

它适用于正确的名称,但不幸的是,它也与下一个错误的名称相匹配:/2020/2020-05/test/o/test。最后一个test无效,我必须拒绝该路径。

正确路径示例:

  • /2020/2020-05/test/o
  • /2020/2020-05/test/o/s(最大结尾处什么都没有)
  • /2020/2020-05/test
  • /2020/2020-05
  • /2020

不正确路径的示例:

  • /2020/2020-05/test/o
  • /2020/2020/2020-05/test/o/smth
  • /2020/2020-05/test/test/o
  • /2020/2020-05/test/o/o/smth
  • 依此类推

但是据我所知,问号匹配零或一次,所以我无法理解表达式的问题。有人可以向我解释吗?

PS 。如果重要的话,我使用 Python 正则表达式。

1 个答案:

答案 0 :(得分:2)

您似乎误添加了最后一个但一个可选组。您需要将其删除:

^/2\d{3}(/2\d{3}-(0[1-9]|1[0-2])(/[a-z ]+(/[go](/s)?)?)?)?$

或者,使用非捕获组以获得更好的性能:

^/2\d{3}(?:/2\d{3}-(?:0[1-9]|1[0-2])(?:/[a-z ]+(?:/[go](?:/s)?)?)?)?$

请参见regex demo

模式详细信息

  • ^-字符串的开头
  • /2-一个/2子字符串
  • \d{3}-三位数字
  • (?:/2\d{3}-(?:0[1-9]|1[0-2])(?:/[a-z ]+(?:/[go](?:/s)?)?)?)?-的可选出现
    • /2\d{3}--/2,然后是任意三位数
    • (?:0[1-9]|1[0-2])-0,然后是任何非零数字或1,后跟012
    • (?:/[a-z ]+(?:/[go](?:/s)?)?)?-的可选出现
      • /[a-z ]+-/,然后是一个或多个空格或小写ASCII字母
      • (?:/[go](?:/s)?)?-的可选出现
        • /[go]-/go
        • (?:/s)?--出现/s
  • $-字符串的结尾。
相关问题