String[] tests = {
"a,b,c,d,e,f",
"a,b,~c~,d,e",
"~a,b,c,d,e~",
"a,b,c,~d,e,f~,g,h,i,~j,k,l,~m,n,o~,q,r,~s,t,u",
};
for (String test : tests) {
System.out.println(
test.replaceAll(
"(^[^~]*~)|([^~]*$)|([^,~]*),|([^,~]*~[^~]*~)",
"$1$2$3$4"
)
);
}
The above prints:
a,b,c,d,e,f
a,b,~c~,d,e
~abcde~
a,b,c,~def~,g,h,i,~jkl~m,n,o~qr~s,t,u
How it works
There are 4 cases:
- We're at the beginning of the string, "outside"
- Just match until we find the first
~
, so next time we'll be "inside"
- So,
(^[^~]*~)
- There are no more
~
till the end of the string
- If there are even number of
~
, we'll be "outside"
- Just match until the end
- So,
([^~]*$)
- If it's none of the above, we're "inside"
- Keep finding the next comma before
~
(so we're still "inside")
- So,
([^,~]*),
(don't capture the comma!)
- If we find
~
instead of a comma, then go out, then go back in on the next ~
In all cases, we make sure we capture enough to reconstruct the string.
References
Related questions