我想要一个匹配仅包含w,x,y或z实例,但不是 w,x,y和z的任何组合的字符串的正则表达式。 " w ... w"是允许的,但不是" w ... x"或者" y ... y ... w"。
我在一些正则表达式测试网站上测试了以下内容,但我正在尝试缩短表达式的长度。有谁知道如何更简洁地表达这一点?
(^(?!.*(x|y|z)).*(w))|(^(?!.*(w|y|z)).*(x))|(^(?!.*(w|x|z)).*(y))|(^(?!.*(w|y|x)).*(z))
答案 0 :(得分:3)
在否定预测中,您可以定义交替捕获组,然后检查是否存在其中一个备选项,除了之前匹配的备选项,其中包含对第一个捕获组值的反向引用的负前瞻。在PCRE正则表达式中,您可以稍后使用(?n)
语法重新使用Group 1子模式。
(?i)^(?!.*(w|x|y|z).*(?!\1)(?1)).*(?1)
请参阅regex demo。
(?i)
会使其不区分大小写。
详细说明:
(?i)
- 不区分大小写的修饰符^
- 字符串的开头(使用/m
修饰符的行)(?!.*(w|x|y|z).*(?!\1)(?1))
- 如果字符串中的w
,x
,y
或z
位于跟随的位置,则会导致匹配失败的否定前瞻使用其中一个值但与捕获到第1组中的值不同.*
- 匹配并使用除换行符以外的0 +个字符(或使用/s
修饰符,包括换行符)(?1)
- 递归第1组中使用的子模式(因此,它与编写(w|x|y|z)
一样)。答案 1 :(得分:0)
这是最快捷的方式^(?=.*([wxyz]))(?:[^wxyz]|\1)+$
^ # BOS
(?=
.* # Lookahead to find
( [wxyz] ) # (1), Either w,x,y or z
)
(?: # Consume the string
[^wxyz] # Not w,x,y or z
| # or,
\1 # Only the captured w,x,y or z allowd
)+
$ # EOS
以下是其他正则表达式和此正则表达式的比较。
示例
zzzzzsadfbzzzzzzz
基准
Regex1: (?i)^(?!.*(w|x|y|z).*(?!\1)(?1)).*(?1)
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 1
Elapsed Time: 2.37 s, 2369.05 ms, 2369051 µs
Regex2: ^(?=.*([wxyz]))(?:[^wxyz]|\1)+$
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 1
Elapsed Time: 0.20 s, 204.42 ms, 204418 µs
如果我是你,我会使用效率更高的人 远离断言中不必要的复杂性。
使用非滚动循环更快^(?=.*([wxyz]))[^wxyz]*(?:\1[^wxyz]*)+$
与多行(?m)^(?=.*([wxyz]))[^wxyz\r\n]*(?:\1[^wxyz\r\n]*)+$
答案 2 :(得分:0)