来自 OP 评论:But in case I have "000000" I would want "0"
修改:
不同字符的重复组如果可能会首先匹配。
事实证明(我相信)找到第一个不同的字符,
导致最大的不同组被重复匹配。
这使得可以使用非贪婪量词来实现这一点
用于大型字符串而不会影响性能。
解读结果:
(注意 - 如果使用支持分支重置的引擎,所有结果都可以
从同一组获得)
第 0 组包含整个匹配项,那么;
要么:
-
第 1 组中不同字符的重复组(最长)
-
第 3 组中相同(单个)字符的重复组
正则表达式:((.)+?(?!\2).+?)\1+|(.)\3+
展开:
( # (1 start), Different chars (at least 2) repeating group
( . )+? # (2), Shortest distance sample character
(?! \2 ) # Border between different characters
.+? # First different, shortest distance
) # (1 end)
\1+
| # or
( . ) # (3), Same character repeating group
\3+
输入:
000010910910901012222
输出:
** Grp 0 - ( pos 0 , len 4 )
0000
** Grp 1 - NULL
** Grp 2 - NULL
** Grp 3 - ( pos 0 , len 1 )
0
-------------
** Grp 0 - ( pos 4 , len 9 )
109109109
** Grp 1 - ( pos 4 , len 3 )
109
** Grp 2 - ( pos 5 , len 1 )
0
** Grp 3 - NULL
-------------
** Grp 0 - ( pos 13 , len 4 )
0101
** Grp 1 - ( pos 13 , len 2 )
01
** Grp 2 - ( pos 13 , len 1 )
0
** Grp 3 - NULL
-------------
** Grp 0 - ( pos 17 , len 4 )
2222
** Grp 1 - NULL
** Grp 2 - NULL
** Grp 3 - ( pos 17 , len 1 )
2
使用分支重置:第 0 组 = 整个匹配,第 1 组 = 重复组。
# (?|((.)+?(?!\2).+?)\1+|(.)\1+)
(?|
( # (1 start), Different chars (at least 2) repeating group
( . )+? # (2), Shortest distance sample character
(?! \2 ) # Border between different characters
.+? # First different, shortest distance
) # (1 end)
\1+
| # or
( . ) # (1), Same character repeating group
\1+
)
对重叠匹配使用单一前瞻。
第 1 组 = 整场比赛,第 2 组 = 不同字符的重复组,第 4 组单个字符重复。
# (?=(((.)+?(?!\3).+?)\2+|(.)\4+))
(?=
( # (1 start), Capture entire match
( # (2 start), Different chars (at least 2) repeating group
( . )+? # (3), Shortest distance sample character
(?! \3 ) # Border between different characters
.+? # First different, shortest distance
) # (2 end)
\2+
| # or
( . ) # (4), Same character repeating group
\4+
) # (1 end)
)
使用 Branch Rreset 和单一前瞻来进行重叠匹配。
第 1 组 = 整场比赛,第 2 组 = 重复组。
# (?=((?|((.)+?(?!\3).+?)\2+|(.)\2+)))
(?=
( # (1 start), Capture entire match
(?|
( # (2 start), Different chars (at least 2) repeating group
( . )+? # (3), Shortest distance sample character
(?! \3 ) # Border between different characters
.+? # First different, shortest distance
) # (2 end)
\2+
| # or
( . ) # (2), Same character repeating group
\2+
)
) # (1 end)
)