This what $regsub does by design: it
removes the part of the string that matches the regular expression and then
replaces it with whatever you have specified in <subtext>. Since you have $null in <subtext> (, $regsub will correctly remove everything. What you actually want is a way to capture the part of the string that you want to keep and put it <subtext>. You already know how to capture stuff with regex: it's the ( ) brackets. What you're missing is the way to put the captured match in <subtext>. This is exactly what \1, \2 do:
Example:
//var %a | !.echo -q $regsub(abCDefgh,/[color:red]([/color][A-Z]*[color:red])[/color]/,[color:red]\1[/color],%a) | echo -s %a
The above command looks for capital letters in the input and keeps them, while removing the lowercase ones.
\1 is the first captured match with (), kinda like $regml(1), but with the significant difference that \1 can be used inside the regex pattern itself. To understand its usage a bit more, take a look at this regex, which finds words that are formed by two identical groups of letters (fex "hehe", "haha", "poopoo" etc):
$regex(<input>,/\b([a-z]+)\1\b/i)
According to the above, your %reg variable should be:
var %reg = /(00[^]*)(00)([^,])|(01[^]*)01([^,])|...
and your $regsub should be: $regsub($1,%reg,\1\2,%a)
What we did is capture every part of the string except the duplicate color. Just because the dupe color is in the middle of the pattern, we need to capture twice, ie the part of the text to the left and right of the dupe color. That's why we also put "\1\2" in <subtext>.
Still, this alias won't catch all cases. For example, if you don't have double digit colors (for colors 0-9), it won't work. You could put a ? right after the leading zero, fex
/(0?0[^]*)(0?0)([^,])|(0?1[^]*)0?1([^,])|...
? matches 0 or 1 time, so this problem is fixed.
If you want to also catch background colors you don't need 16x16 subpatterns. Just the \d (same as [0-9]) and the ? quantifier. This pattern matches ALL valid dupe colors:
/(\d\d?(?:,\d\d?)?)[^]*\1/
Continuing our conversation from the previous post, you are right, my alias does what you say. That's because I mainly made it to work having specific combinations in mind (for example your e1 and e2 aliases). "BBHello" isn't supposed to be generated by those aliases. Making a general-purpose alias that minimizes the number of control codes in any given text is not impossible but it can't be done with a single $regsub (can't? well, not sure, but I think it's pretty much impossible). It can be done with more $regsub's though. Here's what I came up with:
alias mcodes2 {
var %a
!.echo -q $&
$regsub($1,/B((?:[UR]|K(?:\d\d?(?:\x2C\d\d?)?)?)+|)?B/g,\1,%a) $&
$regsub(%a,/U((?:[BR]|K(?:\d\d?(?:\x2C\d\d?)?)?)+|)?U/g,\1,%a) $&
$regsub(%a,/R((?:[UB]|K(?:\d\d?(?:\x2C\d\d?)?)?)+|)?R/g,\1,%a) $&
$regsub(%a,/(?:K(?:\d\d?(?:\x2C\d\d?)?)?)+(K(?:\d\d?(?:\x2C\d\d?)?)?)/g,\1,%a) $&
$regsub(%a,/(K\d[^K]*K[^K\d][^K]*)K(?=\D|$)/g,\1,%a)
if $regex(%a,/(K\d)/) { %a = $remove($left(%a,$calc($regml(1).pos - 1)),K) $+ $mid(%a,$regml(1).pos) }
else %a = $remove(%a,K)
return %a
}
You should replace B with <ctrl+B>, U with <ctrl+U>, R with <ctrl+R> and K with <ctrl+K>. I left it like that so that the code is more understandable. This one is more thoroughly tested than my previous but it's possible that you'll find a bug. Let me know if you do.