我需要匹配一个任意长度的字符串,其中每个字符都有一系列相同长度的相邻重复。
例如aabb
,a
和b
都重复两次,但不重复aabbc
,因为c
也必须重复两次。
下面的图表显示了我想要通过和失败的字符串:
pass | fail |
---|---|
a |
abb |
aa |
aab |
ab |
xyyz |
abc |
foof |
aabb |
abcc |
aabbaa |
abbab |
aabbcc |
|
aaabbb |
|
aaabbbccc |
|
aaaabbbbcccc |
|
wwxxyyzzww |
|
hhiiffggeecchhdd |
您不能用一个正则表达式来实现这一点,但是使用split、filter、map&减少
你可以用任何语言做到这一点;这里有一个使用测试模式的JavaScript片段:
const patterns = [
'a', 'aa', 'ab',
'abc', 'aabb', 'aabbaa',
'aabbcc', 'aaabbb', 'aaabbbccc',
'aaaabbbbcccc', 'wwxxyyzzww', 'hhiiffggeecchhdd',
'abb', 'aab', 'xyyz',
'foof', 'abcc', 'abbab'
];
patterns.forEach((str) => {
let valid = str
.split(/(?<=(.))(?!1)/)
.filter((v, i) => {
return i % 2 === 0;
})
.map((v) => {
return v.length;
})
.reduce((acc, item) => {
if(acc === -1) {
acc = item;
} else if(acc && acc != item) {
acc = 0;
}
return acc;
}, -1);
console.log(str + ' ==> ' + (valid ? true : false));
});
输出:
a ==> true
aa ==> true
ab ==> true
abc ==> true
aabb ==> true
aabbaa ==> true
aabbcc ==> true
aaabbb ==> true
aaabbbccc ==> true
aaaabbbbcccc ==> true
wwxxyyzzww ==> true
hhiiffggeecchhdd ==> true
abb ==> false
aab ==> false
xyyz ==> false
foof ==> false
abcc ==> false
abbab ==> false
说明:
.split(/(?<=(.))(?!1)/)
-在从一个字母到另一个字母的转换中使用正向向后看和反向向前看来拆分字符串.filter()
-从生成的数组中过滤出奇数项;这是因为正向先行(负向先行所需)中的捕获组在结果拆分中显示为元素.map()
-返回每个元素的字符串长度的映射.reduce()
:- 累加器初始化为-1
- 在第一个元素,累加器被设置为项值,例如字符串长度
- 从第二个元素开始,如果项目长度与累加器值不匹配,则累加器设置为0
否。对于任意长度的重复块是不可能的。
没有办法对量词进行反向引用(或类似引用)。
但是,如果最大长度受到限制,例如4:
^(((.)1))+|((.)1{2}))+|((.)1{3}))+)$