`x...(a 和 b)...y` 在有限长度内的正则表达式?

Regex for `x...(a and b)...y` within a limited length?

是否可以在n的有限长度内指定匹配x...(a and b)...y的正则表达式?

更准确地说:

  1. 匹配的xy之间的字符长度最多为n.
  2. 匹配的 xy 之间必须同时存在 ab(无论顺序如何)。
  3. xaby 可以代表多字符字符串片段。

测试用例(假设n = 10):

Match:
...x..a...b..y...
...x..b...a..y...
...x..a...b..y...a...
...x..a...b..y...b...
...x..a...b..y...y...
...x..a.x.b..y...
...x..a.y.b..y...
...xaabbaabbay...
...x..a...b..y... ...x..a...b..y... (2 matches)
...xaby...xaby... (2 matches)

Don't match:
...x..a...b......
...x......b..y...
...x..a......y...
...x..a...b......y...
...x......b..y...a...
...x..a......y...b...
...x..a.y.b......
...x..a.y.b......y...
...x..a.y.b.x....y...
.a.x......b..y...
.b.x..a......y...

P.S:我知道这可以通过简单地匹配 /x.{0,n}y/ 然后检查 ab 是否都存在于许多编程中的匹配字符串中来完成语言。但是,这个问题明确要求 单一正则表达式方法 ,以便它可以在某些应用程序中用作查询,例如 Google Doc 和 Notepad++。

我担心如果不为 xa|b 之间、ab 之间以及 b 之间的部分生成所有有效的长度组合,这是不可能的=12=] 和 y.

对于n=5(即xy之间的ab以外的0-3个字符:

x ( [^ab]{0} ( a ( [^b]{0} b .{0,3}
                 | [^b]{1} b .{0,2}
                 | [^b]{2} b .{0,1}
                 | [^b]{3} b .{0}   )
             | b ( [^b]{0} a .{0,3}
                 | [^b]{1} a .{0,2}
                 | [^b]{2} a .{0,1}
                 | [^b]{3} a .{0}   ) )
  | [^ab]{1} ( a ( [^b]{0} b .{0,2}
                 | [^b]{1} b .{0,1}
                 | [^b]{2} b .{0}   )
             | b ( [^b]{0} a .{0,2}
                 | [^b]{1} a .{0,1}
                 | [^b]{2} a .{0}   ) )
  | [^ab]{2} ( a ( [^b]{0} b .{0,1}
                 | [^b]{1} b .{0}   )
             | b ( [^b]{0} a .{0,1}
                 | [^b]{1} a .{0}   ) )
  | [^ab]{3} ( a ( [^b]{0} b .{0}   )
             | b ( [^b]{0} a .{0}   ) ) ) y

我使用 [^…] 而不是 . 来避免从错误的分支回溯太多,尽管它可能会进一步优化。

我相信你可以使用

x(?:(?(1)(?!)|(a))|(?(2)(?!)|(b))|.){0,10}?y(?(1)|(?!))(?(2)|(?!))

regex demo详情:

  • x - 左手定界符
  • (?:(?(1)(?!)|(a))|(?(2)(?!)|(b))|.){0,10}? - 出现零到十次(但尽可能少)
    • (?(1)(?!)|(a)) - 如果 Group 1 为 null(如果 Group 1 之前未匹配)匹配 a,否则,无法立即触发回溯
    • | - 或
    • (?(2)(?!)|(b)) - 如果 Group 2 为 null(如果 Group 2 之前未匹配)匹配 b,否则,无法立即触发回溯
    • |. - 或任何一个字符(默认情况下除换行字符外)
  • y - 右手定界符
  • (?(1)|(?!)) - 条件构造:如果第 1 组参加了比赛(如果第 1 组的值不为空),则继续,否则,比赛失败
  • (?(2)|(?!)) - 条件构造:如果第 2 组参加了比赛(如果第 2 组的值不为空),则继续,否则,比赛失败。

最后两个条件确保匹配的文本中有 ab

注意:如果ab可以是多字符串,n必须减少到n-(a.length-b.length+2)的长度。所以,如果 aacbbmc,则需要将 10 替换为 10-(2-3+2) => 7。这也意味着您应该事先检查您的预期限制长度限制,它应该允许 ab 组合的长度。

注意 2:在模式的开头添加 (?s) 以将换行符字符与 . 匹配。有关更多选项,请参阅 How do I match any character across multiple lines in a regular expression?