Esta expresión (inspirada en Mike, arriba) parece capturar todos los duplicados, triplicados, etc., incluidos los que están al final de la cadena, lo que la mayoría de los demás no hacen:
/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")
Sé que la pregunta se hace para hacer coincidir solo los duplicados , pero un triplicado son solo 2 duplicados uno al lado del otro :)
Primero, me (^|\s+)
aseguro de que comience con una palabra completa, de lo contrario "filete de niño" iría a "filete de niño" (las "s" coincidirían). Luego, coincide con todas las palabras completas ( (\b\S+\b)
), seguidas de un final de cadena ( $
) o varios espacios ( \s+
), el conjunto se repite más de una vez.
Lo probé así y funcionó bien:
var s = "here here here here is ahi-ahi ahi-ahi ahi-ahi joe's joe's joe's joe's joe's the result result result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))
--> here is ahi-ahi joe's the result
not that that is related
->not that is related
)? Gracias de antemano\1
!\b(\w+)\s+(\1\s*)+\b
?