Validation d'expression régulière d'Eiffel
Question
Comment créez-vous une expression régulière pour une certaine chaîne? Et pouvez-vous le faire dans l'affirmation (partie de condition préalable du code)?
J'ai été sur Google, mais je n'ai rien fait de convaincre.
La question est comme ceci:
Ajoutez une condition préalable à la procédure de création du département (la classe sur laquelle nous travaillons) qui garantit que le numéro de téléphone est valide. Il existe trois formats de numéro de téléphone valides possibles. Un numéro de téléphone valide consiste en un de:
- huit chiffres, dont le premier est non nul
- un zéro leader, un seul code de zone non numérique, puis à huit chiffres, dont le premier est non nul
- Un «+» leader, suivi d'un code de pays à deux chiffres, puis d'un seul code zone non nulle, puis à huit chiffres, dont le premier est non nul
Tous les espaces intégrés doivent être ignorés lors de la validation d'un numéro de téléphone.
Il est acceptable, mais non requis, d'ajouter une classe Phone_number au système dans le cadre de la résolution de ce problème.
La solution
Il y a plusieurs questions différentes à répondre:
Comment vérifier si une chaîne donnée correspond à une expression régulière spécifiée dans Eiffel? On peut utiliser une classe
RX_PCRE_MATCHER
de la bibliothèque gobo. La fonctionnalitécompile
permet de définir l'expression régulière requise et la fonctionnalitérecognizes
Permet de tester si la chaîne correspond.Comment rédiger une expression régulière pour la spécification du numéro de téléphone donné? Quelque chose comme
"(|0[1-9]|\+[0-9]{2}[1-9])[1-9][0-8]{7}"
Devrait faire si je ne l'ai pas vérifié. Il est possible de prendre en compte les espaces blancs intermédiaires dans l'expression régulière elle-même, mais il est beaucoup plus facile de s'en débarrasser avant de passer au correspondant d'expression régulière en appliquantprune_all (' ')
sur la chaîne d'entrée.Comment ajouter une condition préalable à une procédure de création pour vérifier que l'argument le satisfait? Supposons que d'après les éléments précédents, nous avons construit une fonction
is_phone_number
qui prend unSTRING
et renvoie unBOOLEAN
Cela indique si la chaîne spécifiée représente un numéro de téléphone valide. Une solution simple serait d'écriremake (tel: STRING) require is_phone_number (tel) ...
et avoir une fonctionnalité
is_phone_number
dans la classeDEPARTMENT
lui-même. Mais cela nous empêche de vérifier si la chaîne spécifiée représente un numéro de téléphone avant d'appeler cette procédure de création. Il est donc logique de bougeris_phone_number
à la classePHONE_NUMBER_VALIDATOR
cette classeDEPARTMENT
héritera. De même, siPHONE_NUMBER
doit valider la chaîne contre les règles spécifiées, elle peut hériterPHONE_NUMBER_VALIDATOR
et réutilisez la fonctionnalitéis_phone_number
.
Autres conseils
Halikal a en fait travaillé celui-ci, mais ne pas partager jusqu'à présent ...
Cela fonctionne dans Eiffelstudio 6.2 (note - c'est gobo)
http://se.inf.ethz.ch/old/people/leitner/gobo_guidelines/naming_conventions.html
Un numéro de téléphone valide consiste en un de:
- huit chiffres, dont le premier est non nul
- un zéro leader, un seul code de zone non numérique, puis à huit chiffres, dont le premier est non nul
- Un leader + suivi d'un code de pays à deux chiffres, puis d'un seul code de zone non numérique, puis à huit chiffres, dont le premier est non nul
Tous les espaces intégrés doivent être ignorés lors de la validation d'un numéro de téléphone.
require -- 040 is ascii hex space
valid_phone:
match(phone, "^\040*[1-9]\040*([0-9]\040*){7}$") = TRUE or
match(phone, "^\040*0\040*([1-9]\040*){2}([0-9]\040*){7}$") = TRUE or
match(phone, "^\040*\+\040*([0-9]\040*){2}([1-9]\040*){2}([0-9]\040*){7}$") = TRUE
feature --Regular Expression check
match(text: STRING; pattern: STRING): BOOLEAN is
-- checks whether 'text' matches a regular expression 'pattern'
require
text /= Void
pattern /= Void
local
dfa: LX_DFA_REGULAR_EXPRESSION --There's the Trick!
do
create dfa.make
dfa.compile(pattern, True) --There's the Trick!
check -- regex must be compiled before we can use it
dfa.is_compiled;
end
Result := dfa.matches(text)
-- debug: make sure of which pattern
if dfa.matches (text) then
io.putstring(text + " matches " + pattern + "%N")
end
end
end