J'ai vu cet exemple:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Ce qui suit cette syntaxe: ${variable//pattern/replacement}
Malheureusement, le champ pattern
ne semble pas prendre en charge la syntaxe regex complète (si j'utilise .
ou \s
, par exemple, il essaie de faire correspondre les caractères littéraux).
Comment puis-je rechercher/remplacer une chaîne en utilisant la syntaxe regex complète?
Utilisez sed :
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
echo "$MYVAR" | sed -e 's/[a-zA-Z]/X/g' -e 's/[0-9]/N/g'
# prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
Notez que les -e
_ suivants sont traités dans l'ordre. De plus, l'indicateur g
de l'expression correspondra à toutes les occurrences de l'entrée.
Vous pouvez également choisir votre outil préféré en utilisant cette méthode, à savoir Perl, awk, par exemple:
echo "$MYVAR" | Perl -pe 's/[a-zA-Z]/X/g and s/[0-9]/N/g'
Cela vous permettra peut-être de faire plus de correspondances créatives ... Par exemple, dans la capture ci-dessus, le remplacement numérique ne sera pas utilisé à moins d'une correspondance avec la première expression (en raison de lazy and
evaluation). Et bien sûr, vous disposez du support linguistique complet de Perl pour répondre à vos attentes ...
Ceci en fait peut être fait en pur bash:
hello=ho02123ware38384you443d34o3434ingtod38384day
re='(.*)[0-9]+(.*)'
while [[ $hello =~ $re ]]; do
hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]}
done
echo "$hello"
... donne ...
howareyoudoingtodday
Ces exemples fonctionnent aussi en bash sans avoir besoin d'utiliser sed:
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[a-zA-Z]/X}
echo ${MYVAR//[0-9]/N}
vous pouvez également utiliser les expressions de crochet de classe de caractères
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[[:alpha:]]/X}
echo ${MYVAR//[[:digit:]]/N}
sortie
XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
Ce que @Lanaru a voulu savoir, cependant, si je comprends bien la question, c’est pourquoi les extensions "complètes" ou PCRE \s\S\w\W\d\D
etc ne fonctionnent pas comme pris en charge dans php Ruby python etc. Ces extensions proviennent d'expressions régulières (PCRE) compatibles Perl et peuvent ne pas être compatibles avec d'autres formes d'expressions régulières basées sur Shell.
Ceux-ci ne fonctionnent pas:
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//\d/}
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | sed 's/\d//g'
sortie avec tous les caractères "d" littéraux supprimés
ho02123ware38384you44334o3434ingto38384ay
mais ce qui suit fonctionne comme prévu
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | Perl -pe 's/\d//g'
sortie
howareyoudoingtodday
J'espère que cela clarifie un peu plus les choses, mais si vous n'êtes pas encore confus, pourquoi ne pas essayer ceci sur Mac OS X où l'indicateur REG_ENHANCED est activé:
#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day;
echo $MYVAR | grep -o -E '\d'
Sur la plupart des versions de * nix, vous ne verrez que la sortie suivante:
d
d
d
nonJoy!
Si vous effectuez des appels répétés et que vous êtes préoccupé par les performances, ce test révèle que la méthode BASH est environ 15 fois plus rapide que la transmission à sed et probablement à tout autre processus externe.
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]
Utilisez [[:digit:]]
(notez les doubles crochets) comme motif:
$ hello=ho02123ware38384you443d34o3434ingtod38384day
$ echo ${hello//[[:digit:]]/}
howareyoudoingtodday
Je voulais juste résumer les réponses (en particulier les @ nickl https://stackoverflow.com/a/22261334/2916086 ).