Esto se ve como una aplicación clásica de lookbehind positivo, pero lamentablemente Perl no es compatible con eso. De hecho, hacer esto (coincidir con el texto anterior de un personaje en una cadena con una expresión regular completa cuya longitud es indeterminable) solo se puede hacer con clases .NET regex, creo.
Sin embargo, de búsqueda positiva hacia soporta expresiones regulares completos, así que todo lo que necesita hacer es revertir la cadena, se aplican búsqueda positiva hacia delante (como unicornaddict dijo):
perl -pe 's/(.)(?=.*?\1)//g'
y revertir de nuevo, ya que sin la inversa que' Solo mantendré el personaje duplicado en el último lugar de una línea.
EDITAR MASIVO
He pasado la última media hora en esto, y esto parece que esto funciona, sin la marcha atrás.
perl -pe 's/\G$1//g while (/(.).*(?=\1)/g)' FILE_NAME
No sé si estar orgulloso u horrorizado. Básicamente estoy haciendo looakahead positivo, y luego sustituyendo en la cadena con \ G especificado, lo que hace que el motor regex comience su coincidencia desde el último lugar coincidente (representado internamente por la variable pos()).
Con la entrada de prueba como esta:
aabbbcbbccbabb
EFAUUUUH
ABCBBBBD
DEEEFEGGH
AABBCC
La salida es la siguiente:
abc
EFAUH
ABCD
DEFGH
ABC
I pensar está funcionando ...
Explicación - Está bien, en caso de que mi explicación última vez no era lo suficientemente claro - la búsqueda hacia delante irá y parar en el último partido de una variable duplicado [en el código se puede hacer una imprimir pos(); dentro del ciclo para verificar] y s/\ G // g lo eliminará [no necesitas realmente el/g]. Entonces, dentro del ciclo, la sustitución continuará eliminándose hasta que se eliminen todos los duplicados. Por supuesto, esto puede ser un poco demasiado intensivo en el uso del procesador para su gusto ... pero también lo son la mayoría de las soluciones basadas en expresiones regulares que verá. Sin embargo, el método de reversión/anticipación probablemente sea más eficiente que esto.
El orden ha cambiado (por ejemplo, "EFAHU") - me pregunto si es importante. –
@Gavin: eso se puede solucionar invirtiendo la cadena inicialmente, e invertir la cadena después del reemplazo. – kennytm
Bueno, esto es increíble !!!! ¿Pero puede explicarme detalles de bit como qué ===> s/(.) Y (? =. *? \ 1) // está haciendo? También es posible tener en el mismo orden que he puesto en mi consulta inicial, Por ej. actualmente recibo EFAHU en lugar de EFUAH, que es más útil. Thnax a ton :) – manu