Description
Remove consecutive repeated characters of a string, but we have no idea which character will repeat.
Raw Input
ABcccDeeFggggHIJkkk
mnoXXXXpqrYYstZZZZuvw
Desired Output
ABDFHIJ
mnopqrstuvw
Script and Comments
Script1
[ 1] s/(.)\1\1*//g
Comments
  1. When run this and the following script, '-r' option must be used which makes writing parentheses for grouping far more easier since escapings are no longer needed.
  2. Although this script is far more neat than the following one, the latter uses a different approach which you may be interested.
Script2
[ 1] s/^.*/\n&\n/
[ 2] t loop
[ 3] :loop
[ 4] /\n\n/{
[ 5] P
[ 6] d
[ 7] }
[ 8] s/\n(.)(\1.*\n)/\n\2\1/
[ 9] t loop
[10] s/\n(.)/\1\n/
[11] s/(.)(\n.*\n)\1/\2/
[12] s/\n[^\n]*$//
[13] t loop
Comments
  1. '-r' option must be used when you run this script.
  2. We divide Pattern Space (will be abbreviated to PS) into 3 parts separated by newline characters (\n):
    Survived \n Not examined \n Repeated Characters
  3. Given a line, we examine every character from left to right.
  4. Every survived (non-repeated) character will be moved to the left of the first '\n'.
  5. If a character is identified as 'repeated', we move it to the right of the second '\n'.
  6. Each time we examine the first two characters after the first '\n' (X and Y in the following example), assume PS contains
    ... \n X Y....\n Z:
    CaseConditionPS we wantAction
    1X == Y, X == Z\n Y...\n X Z s/\n(.)(\1.*\n)/\2\1/
    2X == Y, X != Z\n Y...\n X
    3X != Y, X == Z\n Y...\n s/\n(.)/\1\n/
    s/(.)(\n.*\n)\1/\2/
    s/\n[^\n]*$/\n/
    4X != Y, X != ZX \n Y..\n
  7. To make 't' of Step [9] branch ONLY when 's' of Step [8] succeeds, due to the nature of command 't', we use Step [2] and [3] to 'reset' the status, or 's' of Step [1] (always succeeds) will make 't' of Step [9] branch even when 's' of Step [8] does not succeed.