Validación de expresión regular de Eiffel
Pregunta
¿Cómo se crea una expresión regular para una determinada cadena?¿Y puedes hacerlo en la Aserción (parte de condición previa del código)?
He estado buscando en Google pero no encontré nada convincente.
La pregunta es así:
Agregue una condición previa al procedimiento de creación del DEPARTAMENTO (la clase en la que estamos trabajando) que garantice que el número de teléfono sea válido.Hay tres posibles formatos de números de teléfono válidos.Un número de teléfono válido consta de uno de:
- ocho dígitos, el primero de los cuales es distinto de cero
- un cero líder, un solo código de área de dígitos distintos de cero, y luego ocho dígitos, el primero de los cuales no es cero
- un '+' principal, seguido de un código de país de dos dígitos, luego un solo código de área de dígitos distintos de cero, y luego ocho dígitos, el primero de los cuales no es cero
Cualquier espacio incrustado debe ignorarse al validar un número de teléfono.
Es aceptable, pero no es necesario, agregar una clase Phone_Number al sistema como parte de la resolución de este problema.
Solución
Hay varias preguntas diferentes que deben responderse:
¿Cómo comprobar si una cadena determinada coincide con una expresión regular especificada en Eiffel?Se puede usar una clase.
RX_PCRE_MATCHER
de la biblioteca de gobos.La característicacompile
permite configurar la expresión regular requerida y la característicarecognizes
permite probar si la cadena coincide.¿Cómo escribir una expresión regular para la especificación del número de teléfono dado?Algo como
"(|0[1-9]|\+[0-9]{2}[1-9])[1-9][0-8]{7}"
debería hacerlo aunque no lo he comprobado.Es posible tener en cuenta los espacios en blanco intermedios en la propia expresión regular, pero es mucho más fácil deshacerse de ellos antes de pasar al comparador de expresiones regulares aplicandoprune_all (' ')
en la cadena de entrada.¿Cómo agregar una condición previa a un procedimiento de creación para verificar que el argumento la satisface?Supongamos que a partir de los elementos anteriores construimos una función
is_phone_number
eso toma unSTRING
y devuelve unBOOLEAN
que indica si la cadena especificada representa un número de teléfono válido.Una solución sencilla sería escribirmake (tel: STRING) require is_phone_number (tel) ...
y tener una característica
is_phone_number
en la claseDEPARTMENT
sí mismo.Pero esto nos impide verificar si la cadena especificada representa un número de teléfono antes de llamar a este procedimiento de creación.Entonces tiene sentido moverseis_phone_number
a la clasePHONE_NUMBER_VALIDATOR
esa claseDEPARTMENT
heredará.De manera similar, siPHONE_NUMBER
necesita validar la cadena contra reglas especificadas, puede heredarPHONE_NUMBER_VALIDATOR
y reutilizar la funciónis_phone_number
.
Otros consejos
Halikal en realidad trabajó esto, pero Dud no compartir hasta ahora ...
Esto funciona en Eiffelstudio 6.2 (Nota - Este es Gobo)
http://se.inf.ethz.ch/Old / People / Leitner / Gobo_Guidelines / Naming_conventions.html
Un número de teléfono válido consiste en uno de:
- Ocho dígitos, el primero de los cuales no es cero
- un cero líder, un único código de área de dígitos no cero, y luego ocho dígitos, el primero de los cuales no es cero
- un líder + seguido de un código de país de dos dígitos,
Luego, un solo código de área de dígitos no cero, y luego ocho dígitos,
El primero de los cuales no es cero
Cualquier espacios integrados deben ser ignorados al validar un número de teléfono.
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