2009-12-07 6 views
1

J'ai besoin d'un moyen de trouver des mots qui contiennent n'importe quelle combinaison de caractères et de chiffres mais exactement 4 chiffres seulement, et au moins un caractère.Expression régulière Grep pour 4 chiffres entre chaîne de caractères de longueur variable

Exemple:

a1a1a1a1  // Match 
1234   // NO match (no characters) 
a1a1a1a1a1  // NO match 
ab2b2   // NO match 
cd12   // NO match 
z9989   // Match 
1ab26a9   // Match 
1ab1c1   // NO match 
12345   // NO match 
24    // NO match 
a2b2c2d2  // Match 
ab11cd22dd33 // NO match 
+0

pourquoi pas "1234"? il a exactement 4 chiffres. vous devez être plus précis sur vos besoins. –

+0

Je veux dire toute combinaison de l'omble chevalier et chiffres (les deux CHARS chiffres) test de chat de ab2b2 CD12 z9989 1ab26a9 1ab1c1 a2b2c2d2 ab11cd22dd33 sortie valide doit être a2b2c2d2 z9989 1ab26a9 – Leo

Répondre

0

Avec grep:

grep -iE '^([a-z]*[0-9]){4}[a-z]*$' | grep -vE '^[0-9]{4}$' 

Est-ce que dans un motif avec Perl:

perl -ne 'print if /^(?!\d{4}$)([^\W\d_]*\d){4}[^\W\d_]*$/' 

La classe de personnage [^\W\d_] géniale est une façon cosmopolite épeler [A-Za-z] : il attrape toutes les lettres plutôt que seulement l'Eng ceux qui sont

0

En supposant que vous avez seulement besoin ASCII, et vous ne pouvez accéder aux (assez primitifs) constructions regexp de grep, ce qui suit devrait être assez proche:

grep ^[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*$ | grep [a-zA-Z] 
0

Vous pouvez essayer

[^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]* 

Mais Cela correspondra à 1234. Pourquoi cela ne correspond-il pas à vos critères?

3

Pour correspondre à un chiffre dans grep, vous pouvez utiliser [0-9]. Pour correspondre à tout sauf à un chiffre, vous pouvez utiliser [^ 0-9]. Puisque cela peut être n'importe quel nombre de chars, ou aucun, vous ajoutez un "*" (n'importe quel nombre du précédent). Donc ce que vous aurez envie est logiquement

(anything not a digit or nothing)* (any single digit) (anything not a digit or nothing)* . ...

jusqu'à ce que vous avez 4 « un chiffre unique » des groupes. ie [^ 0-9] * [0-9] ...

Je trouve avec les modèles longs grep, en particulier avec de longues chaînes de caractères spéciaux qui doivent être échappés, il est préférable de construire lentement afin que vous soyez Assurez-vous de comprendre ce qui se passe. Par exemple,

#this will highlight your matches, and make it easier to understand 
alias grep='grep --color=auto' 
echo 'a1b2' | grep '[0-9]' 

va vous montrer comment cela correspond. Vous pouvez ensuite étendre le motif une fois que vous avez compris chaque partie.

0

Le regex en est:

([A-Za-z]\d){4} 
  • [A-Za-z] - pour la classe de caractères
  • \ d - pour le nombre
  • vous les WRAPP en() pour les regrouper indiquant le caractère de format suivre par numéro
  • {4} - indiquant qu'il doit être de 4 répétitions
2

Je ne suis pas sûr de toutes les autres entrées que vous pourriez prendre (c.-à-d. est ax12ax12ax12ax12 valide?), Mais cela fonctionnera sur la base de ce que vous avez publié:

%> grep -P "^(?:\w\d){4}$" fileWithInput 
+0

Vous pourrait vouloir utiliser la limite de mot '\ b' au lieu de BOL (^) et EOL ($) dans certaines circonstances. –

+0

@Dennis. Bon point. Je l'écrivais pour correspondre à l'entrée qu'il a donnée, mais s'il y a plusieurs mots par ligne alors oui je devrais utiliser le \ b à la place de^et $. –

1

Si vous ne me dérange pas en utilisant une petite coquille aussi bien, vous pourriez faire quelque chose comme ceci:

echo "a1a1a1a1" |grep -o '[0-9]'|wc -l 

qui afficherait la nombre de chiffres trouvés dans la chaîne. Si vous le souhaitez, vous pouvez alors tester un certain nombre de matches:

max_match=4 
[ "$(echo "a1da4a3aaa4a4" | grep -o '[0-9]'|wc -l)" -le $max_match ] || echo "too many digits." 
0

vous pouvez utiliser script shell normal, pas besoin regex compliqué.

var=a1a1a1a1 
alldigits=${var//[^0-9]/} 
allletters=${var//[0-9]/} 
case "${#alldigits}" in 
    4) 
    if [ "${#allletters}" -gt 0 ];then 
     echo "ok: 4 digits and letters: $var" 
    else 
     echo "Invalid: all numbers and exactly 4: $var" 
    fi 
    ;; 
    *) echo "Invalid: $var";; 
esac 
+0

i écrit le actualy scénario :) #/bin/bash echo "$ @ pour" |! Tr-s "" "\ n" s >> tri chat tri | while read tostr faire l = $ (echo $ tostr | tr -d "\ n" | wc -c) temp = $ (echo $ tostr | tr -d az | tr -d "\ n" | wc -c) if [$ temp -eq 4 ], puis si [$ l -gt 4]; puis printf "% s" "$ tostr" fi fi fait echo – Leo

0

merci pour vos réponses i écrit finaly un script et un travail parfait: ./P ab2b2 cd12 z9989 1ab26a9 1ab1c1 1234 24 a2b2c2d2

#!/bin/bash 
echo "[email protected]" |tr -s " " "\n"s >> sorting 
cat sorting | while read tostr 
do 
    l=$(echo $tostr|tr -d "\n"|wc -c) 
    temp=$(echo $tostr|tr -d a-z|tr -d "\n" | wc -c) 

    if [ $temp -eq 4 ]; then 
    if [ $l -gt 4 ]; then 
     printf "%s " "$tostr" 
    fi 
    fi 
done 
echo 
Questions connexes