Me gustaría usar sed
o perl
reemplazar todas las apariciones de una palabra que no tiene una palabra determinada en frente.
Por ejemplo, tengo un archivo de texto que contiene una trama de una película y quiero reemplazar todas las apariciones del apellido de un personaje con su nombre, pero solo si su nombre no aparece inmediatamente antes de su apellido.
El texto de muestra podría verse así:
John Smith and Jane Johnson talk about Smith's car.
Quiero que se vea así:
John Smith and Jane Johnson talk about John's car.
Si solo lo hago sed 's/Smith/John/' file
, entonces tendría:
John John and Jane Johnson talk about John's car.
El primer nombre que viene antes del apellido siempre será el mismo. No tengo que lidiar con John Smith
y Frank Smith
. Solo necesito una forma de igualar Smith
que no tenga John
precedente.
sed
regular-expression
perl
jonescb
fuente
fuente
Respuestas:
Sería fácil con cualquier lenguaje donde las expresiones regulares sean capaces de mirar hacia atrás. Por supuesto, Perl es el primero en la lista:
El punto débil es tener más de un carácter sin palabras entre "John" y "Smith". Desafortunadamente, un cuantificador como
+
for\W
generaría el error "Longitud variable mirando hacia atrás no implementado".fuente
EDITAR ... re su comentario ... Aquí hay un nuevo guión que no se preocupa por (por ejemplo) William Smith. Temporalmente ofusca los patrones que mantiene como Smith (sin cambios).
Si le preocupa el Sr. Sr. Sra. ... entonces esto funciona.
Puede atender a William agregando su nombre a la lista o , por ejemplo.
sed -r 's/\<(William|John|...
Este es el guión original
fuente
El () capturará el nombre que no sea el Nombre antes del Apellido, por lo que se volverán a consultar en el reemplazo.
Editar
@ manatwork, gilles
Tienes razón. Qué tal si
Esto parece hacer el truco.
fuente
[^John]
coincide con un carácter que debe ser uno deJ
,o
,h
on
. Dudo que esto sea lo que pretendías. No existe una construcción de negación en las expresiones regulares (Perl tiene(?!…)
y(?<!…)
, pero si lo considera una negación, probablemente no hará lo que espera).sed
sin él hace que la lógica sed hinchada ...temp1
casi siempre estará bien, ¡pero! cuidado con ese autobús. Para mitigar esta posibilidad, creo que es mejor usar caracteres que (casi) nunca aparecen en los archivos de texto de Latin-Script, por ejemplo, valor hexadecimal \ x01 \ x02, o combinaciones de ellos, o tal vez \ xe188b4 UTF-8 locale (ሴ - VER SÍLABLE ETIÓPICO) .. ej.echo -e 'Z' |sed 's/./\xe1\x88\xb4/'
=>ሴ
cuando la configuración regional es UTF-8 ..