J'essaie de prendre un bloc de nombres qui peut ou non avoir des séparateurs et de les renvoyer dans un format standard. En utilisant le SSN comme exemple:
ex1="An example 123-45-6789"
ex2="123.45.6789 some more things"
ex3="123456789 thank you Ruby may I have another"
devrait tous aller dans une méthode qui retourne "123-45-6789" En gros, tout (sauf rien) à l'exception d'un chiffre ou d'une lettre doit renvoyer un SSN au format XXX-XX-XXXX. La partie agrafante est un moyen pour les expressions régulières d'identifier qu'il ne peut y avoir rien.
Ce que j'ai jusqu'à présent dans l'identification de mon SSN:
def format_ssns(string)
string.scan(/\d{3}[^0-9a-zA-Z]{1}\d{2}[^0-9a-zA-Z]{1}\d{4}/).to_a
end
Cela semble fonctionner pour tout ce que je prévois SAUF lorsqu'il n'y a rien. "123456789" ne fonctionne pas. Puis-je utiliser des expressions régulières dans ce cas pour identifier un manque?
Avez-vous essayé de faire correspondre 0 ou 1 caractères entre vos numéros?
\d{3}[^0-9a-zA-Z]{0,1}\d{2}[^0-9a-zA-Z]{0,1}\d{4}
Cela a déjà été partagé dans un commentaire, mais juste pour fournir une réponse complète-ish ...
Vous avez ces outils à votre disposition:
x
correspond à x
exactement une foisx{a,b}
correspond à x
entre a
et b
foisx{a,}
correspond à x
au moins a
foisx{,b}
correspond à x
jusqu'à (un maximum de) b
foisx*
correspond à x
zéro fois ou plus (identique à x{0,}
)x+
correspond à x
une ou plusieurs fois (identique à x{1,}
)x?
correspond à x
zéro ou une fois (identique à x{0,1}
)Donc, vous voulez utiliser ce dernier, car c'est exactement ce que vous recherchez (zéro ou une fois).
/\d{3}[^0-9a-zA-Z]?\d{2}[^0-9a-zA-Z]?\d{4}/
Votre expression rationnelle actuelle autorisera 123-45[6789
, sans parler de tous les types de caractères Unicode et de caractères de contrôle. Dans le cas extrême:
123
45師6789
est considéré comme correspondant à votre expression rationnelle.
Vous pouvez utiliser backreference pour vous assurer que le séparateur est identique.
/\d{3}([.-]?)\d{2}\1\d{4}/
[.-]?
correspondra soit .
, -
ou rien (en raison du quantificateur optionnel ?
). Ce qui correspond ici sera utilisé pour s'assurer que le second séparateur est identique via backreference.
Whelp ... on dirait que je viens de trouver ma propre réponse, mais tout indice d'amélioration serait utile.
def format_ssns(string)
string.scan(/\d{3}[^0-9a-zA-Z]{0,1}\d{2}[^0-9a-zA-Z]{1}\d{4}/).to_a
end
Semble faire l'affaire.