如果先前的正则表达式匹配,如何有条件地期望特定字符



我希望只有在前面的正则表达式匹配的情况下才需要一些字符。如果不是,则不需要任何字符(空字符串(。例如,如果在前四个字符之后出现组(A10、B32、C56、D65(中的一个字符串(枚举类型(_"然后是一个3位数的数字,如123。如果没有出现上述组中的任何元素,则不需要其他字符串。我的第一次尝试是这样的,但ELSE分支不起作用:

^XXX_(?<DT>A12|B43|D14)(?(DT)(_d{1,3})|).ZZZ$
  • XXX_A12_123.ZZZ->匹配
  • XXX_A11.ZZZ->匹配
  • XXX_A12_abc.ZZZ->没有匹配
  • XXX_A23_123.ZZZ->没有匹配

这些是文件名的示例。如果文件名包含一个上述组的字符串,如A12或C56,那么我希望这个元素后面跟着一个下划线,后面跟着1到3位数字。如果文件名不包含该组的字符串(没有字符或与组中的字符串不同的字符序列(,那么我不希望看到后面跟着1到3位数字的下划线。

例如,我可以将正则表达式扩展到

^XXX_(?<DT>A12|B43|D14)_d{5}(?(DT)(_d{1,3})|)_someMoreChars.ZZZ$

然后我希望这些文件名是有效的:

  • XXX_A12_12345_123_wellDone.ZZZ
  • XXX_Q21_00000_wellDone.ZZZ
  • XXX_Q21_00000_456-wellDone.ZZZ

。。。但这是无效的:

  • XXX_A12_12345_wellDone.ZZZ

如何使条件语句的ELSE分支工作?

最后,我打算有两个小组A组:(A11、B32、D76、R33(B组:(A23、C56、H78、T99(

如果组A的一个元素出现在文件名中,那么我希望在该文件名中找到_\d{1,3}。如果组B的元素出现在文件名中,则_\d{1,3}应是可选的(它可能出现在文件中,也可能不出现(。

我最终得到了这个正则表达式:

^XXX_(?:(?A12|B43|D14((?(?(DT((_\d{5}_\d{1,3}(|(?!(?&DT(((?!.*_\d{3}(?!\d(((.*\.ZZZ$
^XXX_(?:(?<DT>A12|B43|D14))?_d{5}(?(DT)(_d{1,3})|(?!(?&DT))(?!.*_d{3}(?!d))).+.ZZZ$

由于我必须在OpenApi@Pattern注释中使用这个正则表达式,我遇到了错误:

此regex方言不支持条件。

As@第四只鸟建议的交替似乎奏效了:

XXX_((((A12|B43|D14)_d{5}_d{1,3}))|((?:(A10|B10|C20)((?:_d{5}_d{3})|(?:_d{3}))))).*.ZZZ$

else分支是|之后的部分,但如果您也想匹配第二个示例,则if子句将不起作用,因为您已经匹配了A12|B43|D14中的一个

命名捕获组不是可选的,因此if子句将始终为true。

相反,您可以使用交替来匹配后面跟着下划线和3位数字的记数部分,或者匹配大写字符和2位数字。

^XXX_(?:(?<DT>A12|B43|D14)_d{1,3}|[A-Z]d{2}).ZZZ$

Regex演示

如果要使用If/else子句,可以将命名的捕获组设置为可选,然后检查组1是否存在。

^XXX_(?<DT>A12|B43|D14)?(?(DT)_d{1,3}|[A-Z]d{2}).ZZZ$

Regex演示

对于更新的问题:

^XXX_(?<DT>A12|B43|D14)?(?(DT)(?:_d{5})?_d{3}(?!d)|(?!A12|B43|D14|[A-Z]d{2}_d{3}(?!d))).*.ZZZ$

模式匹配:

  • ^字符串开始
  • XXX_按字面匹配
  • (?<DT>A12|B43|D14)?
  • (?(DT)如果我们有DT组
    • (?:_d{5})?可选匹配_和5位数字
    • _d{3}(?!d)匹配_和3位数字
    • |
    • (?!否定前瞻,断言不向右
      • A12|B43|D14|匹配其中一个备选方案,或
      • [A-Z]d{2}_d{3}(?!d)匹配1个字符A-Z,2个数字_3个数字后面没有数字
    • )关闭前瞻
  • )关闭if子句
  • .*匹配行的其余部分
  • .ZZZ匹配.和ZZZ
  • $字符串结束

Regex演示

最新更新