Regex: reemplaza todos los personajes después del 15 con '...'

votos
2

Estoy tratando de hacer algunas cosas de formato simple con 'sed' en Linux, y tengo que usar una expresión regular para recortar una cadena después del 15 ° personaje, y agregar un '...' hasta el final. Algo como esto:

before: this is a long string that needs to be shortened
after: this is a long ...

¿Alguien puede por favor mostrarme cómo podría escribir esto como una expresión regular, y si es posible explicar cómo funciona para que pueda aprender Regex un poco mejor?

Publicado el 09/12/2008 a las 22:35
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
17

Lo siguiente funciona para mí:

echo "This is a test with more than 15 characters" | sed "s/\(.\{15\}\).\+$/\1…/"

Lo que sucede aquí es que hacemos coincidir cualquier caracter ( .) 15 veces ( {15}). Capturamos el texto que coincide entre paréntesis. La siguiente parte ( .+$) coincide con todo el resto, hasta el final de la línea. Reemplazamos esto por lo que hemos capturado dentro de los paréntesis ( \1), seguido de los puntos suspensivos hiperbólicos.

Para satisfacer sedel dialecto regex (BRE) tenemos que escapar de algunos de los personajes.

Respondida el 09/12/2008 a las 22:38
fuente por usuario

votos
6

Explicación de la respuesta de Konrand Rudolph, ya que solicitó explicaciones (¡ah, mientras escribía esto, Konrad también agregó su propia explicación!)

 sed "s/\(.\{15\}\).+$/\1…/"

\( 

Comience un grupo: solicite al motor de expresiones regulares que recuerde qué hay dentro de los pares y asigne el primer grupo a \ 1, el segundo a \ 2, etc. Solo necesitaremos \ 1 aquí.

.

Coincidir todo ...

\{15\}

... 15 veces.

\)

termina el grupo. So \ 1 contendrá los primeros 15 caracteres

 .+

hacer coincidir algo de nuevo. El + significa "una o más veces", por lo que coincidirá con los caracteres más allá de los 15 caracteres con los que coincidimos anteriormente, ...

 $

... hasta el final de la línea

Ahora para el bit de reemplazo:

\1

Reemplazar con el contenido de \ 1

...

y tres puntos

¡Hecho!

Respondida el 09/12/2008 a las 22:46
fuente por usuario

votos
1

Con expresiones regulares de Perl:

$ echo 'this is a long string that needs to be shortened' \
| perl -pe 's/^(.{15}).+/$1.../'
this is a long ...

La manera más fácil de pensar sobre expresiones regulares es considerarlo un patrón que debe ser igualado. En este caso, el patrón comienza con el comienzo de la línea:

^

(Tenga en cuenta que /es un separador arbitrario. En su lugar, podrían usarse otros caracteres). ^Es el símbolo que representa el inicio de la línea en una expresión regular. A continuación, la expresión regular coincide con cualquier carácter:

^.

A .es el símbolo de expresión regular para cualquier personaje. Pero queremos hacer coincidir los primeros 15 caracteres:

^.{15}

Hay varios modificadores diferentes que representan una repetición. El más común es el *que significa 0 o más. A +indica 1 o más. {15}obviamente representa exactamente 15. (Las {...}anotaciones son más generales. Así que *podría escribirse {0,}y +es lo mismo que {1,}.) Ahora tenemos que capturar los primeros 15 caracteres para que podamos usarlos más adelante:

^(.{15})

Todo entre (y )es capturado y colocado en una variable especial llamada $1(o a veces \1). El segundo pedazo capturado se colocará en $2y así sucesivamente. Finalmente, debe hacer coincidir hasta el final de la línea para poder descartar esa parte:

^(.{15}).+

Inicialmente lo usé *, pero como señaló otra persona, probablemente eso no es lo que se quiere cuando la cadena tiene exactamente 15 caracteres:

$ echo 'this is a long ' \
| perl -pe 's/^(.{15}).*/$1.../'
this is a long ...

Si utiliza un +medio, el patrón no coincidirá si no hay un 16º carácter para reemplazar.

La segunda mitad de la declaración es lo que se imprime:

$1...

La $1variable que captamos antes se usa y los puntos son literales .en este lado de la sustitución. Generalmente, todo excepto las variables regex son literales en el lado derecho de una declaración de sustitución.

Respondida el 09/12/2008 a las 22:39
fuente por usuario

votos
0

¿De verdad quieres acabar con todo después del 15to personaje, o estás tratando de imponer una longitud máxima de 15 caracteres? ¿Qué pasa si la cadena tiene 16 caracteres de largo? Todas las soluciones presentadas hasta ahora cortarán ese carácter sobrante solo para reemplazarlo por tres puntos. (Sé que Konrad y Paul usaron el personaje de la elipsis, pero el OP usó tres puntos en el ejemplo: deberíamos obtener un fallo al respecto).

Si desea recortar las cuerdas hasta una longitud máxima de 15 incluyendo los tres puntos , puede hacer esto:

s/^\(.\{12\}\).\{3\}.\+$/\1.../

Todavía solo coincide si hay más de 15 caracteres, pero luego corta todo después del 12 ° personaje para dejar espacio para los puntos.

Respondida el 10/12/2008 a las 05:06
fuente por usuario

votos
0

En Perl, podrías escribir s/(.{15}).*/$1.../. No estoy seguro si sed puede usar la notación {15} pero si no, s/\(...............\).*/\1.../(con 15 puntos en el grupo).

Nunca puedo recordar si necesita escapar (cuando se agrupa en sed. Lo intenté y tú sí necesitas \(y\)

Respondida el 09/12/2008 a las 22:42
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more