expresiones - regex online
Buscar y reemplazar en bash usando expresiones regulares (5)
He visto este ejemplo:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Que sigue esta sintaxis: ${variable//pattern/replacement}
Lamentablemente, el campo de pattern
no parece ser compatible con la sintaxis completa de expresiones regulares (si utilizo .
O /s
, por ejemplo, intenta hacer coincidir los caracteres literales).
¿Cómo puedo buscar / reemplazar una cadena usando la sintaxis completa de expresiones regulares?
Esto realmente se puede hacer en puro bash:
hello=ho02123ware38384you443d34o3434ingtod38384day
re=''(.*)[0-9]+(.*)''
while [[ $hello =~ $re ]]; do
hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]}
done
echo "$hello"
... cede ...
howareyoudoingtodday
Estos ejemplos también funcionan en bash sin necesidad de usar sed:
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[a-zA-Z]/X}
echo ${MYVAR//[0-9]/N}
también puedes usar expresiones de corchetes de clases de caracteres
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[[:alpha:]]/X}
echo ${MYVAR//[[:digit:]]/N}
salida
XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
Lo que @Lanaru quería saber, sin embargo, si entiendo la pregunta correctamente, es por qué las extensiones "completas" o PCRE /s/S/w/W/d/D
etc. no funcionan como se admiten en php ruby python, etc. las extensiones son de expresiones regulares compatibles con Perl (PCRE) y pueden no ser compatibles con otras formas de expresiones regulares basadas en shell.
Estos no funcionan:
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello///d/}
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | sed ''s//d//g''
salida con todos los caracteres "d" literales eliminados
ho02123ware38384you44334o3434ingto38384ay
pero el siguiente funciona como se esperaba
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | perl -pe ''s//d//g''
salida
howareyoudoingtodday
Espero que aclare las cosas un poco más, pero si aún no está confundido, ¿por qué no prueba esto en Mac OS X que tiene habilitado el indicador REG_ENHANCED?
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day;
echo $MYVAR | grep -o -E ''/d''
En la mayoría de los sabores de * nix, solo verá la siguiente salida:
d
d
d
nJoy!
Si realiza llamadas repetidas y está preocupado por el rendimiento, esta prueba revela que el método BASH es ~ 15 veces más rápido que bifurcar y probablemente cualquier otro proceso externo.
hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X
P1=$(date +%s)
for i in {1..10000}
do
echo $hello | sed s/X//g > /dev/null
done
P2=$(date +%s)
echo $[$P2-$P1]
for i in {1..10000}
do
echo ${hello//X/} > /dev/null
done
P3=$(date +%s)
echo $[$P3-$P2]
Use sed :
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
echo $MYVAR | sed -e ''s/[a-zA-Z]/X/g'' -e ''s/[0-9]/N/g''
# prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
Tenga en cuenta que las siguientes '' -e
'' se procesan en orden. Además, la bandera g
de la expresión coincidirá con todas las ocurrencias en la entrada.
También puede elegir su herramienta favorita utilizando este método, es decir, perl, awk, por ejemplo:
echo $MYVAR | perl -pe ''s/[a-zA-Z]/X/g and s/[0-9]/N/g''
Esto puede permitirle hacer más coincidencias creativas ... Por ejemplo, en el recorte anterior, la sustitución numérica no se usaría a menos que hubiera una coincidencia en la primera expresión (debido a la pereza and
evaluación). Y, por supuesto, tiene el soporte de idioma completo de Perl para hacer su oferta ...
Use [[:digit:]]
(tenga en cuenta los corchetes dobles) como patrón:
$ hello=ho02123ware38384you443d34o3434ingtod38384day
$ echo ${hello//[[:digit:]]/}
howareyoudoingtodday
Solo quería resumir las respuestas (especialmente @ nickl-s https://.com/a/22261334/2916086 ).