`x...(a 和 b)...y` 在有限长度内的正则表达式?
Regex for `x...(a and b)...y` within a limited length?
是否可以在n
的有限长度内指定匹配x...(a and b)...y
的正则表达式?
更准确地说:
- 匹配的
x
和y
之间的字符长度最多为n
.
- 匹配的
x
和 y
之间必须同时存在 a
和 b
(无论顺序如何)。
x
、a
、b
和 y
可以代表多字符字符串片段。
测试用例(假设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/
然后检查 a
和 b
是否都存在于许多编程中的匹配字符串中来完成语言。但是,这个问题明确要求 单一正则表达式方法 ,以便它可以在某些应用程序中用作查询,例如 Google Doc 和 Notepad++。
我担心如果不为 x
和 a|b
之间、a
和 b
之间以及 b
之间的部分生成所有有效的长度组合,这是不可能的=12=] 和 y
.
对于n=5(即x
和y
之间的a
和b
以外的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 组的值不为空),则继续,否则,比赛失败。
最后两个条件确保匹配的文本中有 a
和 b
。
注意:如果a
和b
可以是多字符串,n
必须减少到n-(a.length-b.length+2)
的长度。所以,如果 a
是 ac
而 b
是 bmc
,则需要将 10
替换为 10-(2-3+2)
=> 7
。这也意味着您应该事先检查您的预期限制长度限制,它应该允许 a
和 b
组合的长度。
注意 2:在模式的开头添加 (?s)
以将换行符字符与 .
匹配。有关更多选项,请参阅 How do I match any character across multiple lines in a regular expression?。
是否可以在n
的有限长度内指定匹配x...(a and b)...y
的正则表达式?
更准确地说:
- 匹配的
x
和y
之间的字符长度最多为n
. - 匹配的
x
和y
之间必须同时存在a
和b
(无论顺序如何)。 x
、a
、b
和y
可以代表多字符字符串片段。
测试用例(假设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/
然后检查 a
和 b
是否都存在于许多编程中的匹配字符串中来完成语言。但是,这个问题明确要求 单一正则表达式方法 ,以便它可以在某些应用程序中用作查询,例如 Google Doc 和 Notepad++。
我担心如果不为 x
和 a|b
之间、a
和 b
之间以及 b
之间的部分生成所有有效的长度组合,这是不可能的=12=] 和 y
.
对于n=5(即x
和y
之间的a
和b
以外的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 组的值不为空),则继续,否则,比赛失败。
最后两个条件确保匹配的文本中有 a
和 b
。
注意:如果a
和b
可以是多字符串,n
必须减少到n-(a.length-b.length+2)
的长度。所以,如果 a
是 ac
而 b
是 bmc
,则需要将 10
替换为 10-(2-3+2)
=> 7
。这也意味着您应该事先检查您的预期限制长度限制,它应该允许 a
和 b
组合的长度。
注意 2:在模式的开头添加 (?s)
以将换行符字符与 .
匹配。有关更多选项,请参阅 How do I match any character across multiple lines in a regular expression?。