How about this?
String resultString = subjectString.replaceAll("((?::0\b){2,}):?(?!\S*\b\1:0\b)(\S*)", "::$2").replaceFirst("^0::","::");
Explanation without Java double-backslash hell:
( # Match and capture in backreference 1:
(?: # Match this group:
:0 # :0
# word boundary
){2,} # twice or more
) # End of capturing group 1
:? # Match a : if present (not at the end of the address)
(?! # Now assert that we can't match the following here:
S* # Any non-space character sequence
# word boundary
1 # the previous match
:0 # followed by another :0
# word boundary
) # End of lookahead. This ensures that there is not a longer
# sequence of ":0"s in this address.
(S*) # Capture the rest of the address in backreference 2.
# This is necessary to jump over any sequences of ":0"s
# that are of the same length as the first one.
Input:
2001:db8:0:0:0:0:2:1
2001:db8:0:1:1:1:1:1
2001:0:0:1:0:0:0:1
2001:db8:0:0:1:0:0:1
2001:db8:0:0:1:0:0:0
Output:
2001:db8::2:1
2001:db8:0:1:1:1:1:1
2001:0:0:1::1
2001:db8::1:0:0:1
2001:db8:0:0:1::
(I hope the last example is correct - or is there another rule if the address ends in 0
?)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…