Validação de expressão regular Eiffel
Pergunta
Como você cria uma expressão regular para uma determinada string?E você pode fazer isso na Asserção (parte de pré-condição do código)?
Estive pesquisando no Google, mas não consegui nada convincente.
A questão é assim:
Adicione uma pré-condição ao procedimento de criação DEPARTMENT (a classe em que estamos trabalhando) que garante que o número de telefone seja válido.Existem três formatos de número de telefone válidos possíveis.Um número de telefone válido consiste em um dos seguintes:
- oito dígitos, o primeiro dos quais é diferente de zero
- um zero líder, um único código de área de dígitos diferentes de zero e depois oito dígitos, o primeiro dos quais é diferente de zero
- um líder '+', seguido por um código de dois dígitos do país, depois um único código de área de dígitos diferentes de zero e depois oito dígitos, o primeiro dos quais é diferente de zero
Quaisquer espaços incorporados devem ser ignorados ao validar um número de telefone.
É aceitável, mas não é necessário, adicionar uma classe Phone_Number ao sistema como parte da resolução desse problema.
Solução
Existem várias perguntas diferentes a serem respondidas:
Como verificar se uma determinada string corresponde a uma expressão regular especificada em Eiffel?Pode-se usar uma classe
RX_PCRE_MATCHER
da biblioteca Gobo.A característicacompile
permite definir a expressão regular necessária e o recursorecognizes
permite testar se a string corresponde a ela.Como escrever uma expressão regular para a especificação de número de telefone fornecida?Algo como
"(|0[1-9]|\+[0-9]{2}[1-9])[1-9][0-8]{7}"
deveria fazer, embora eu não tenha verificado.É possível levar em conta os espaços em branco intermediários na própria expressão regular, mas é muito mais fácil se livrar deles antes de passar para o correspondente de expressão regular aplicandoprune_all (' ')
na string de entrada.Como adicionar uma pré-condição a um procedimento de criação para verificar se o argumento o satisfaz?Vamos supor que a partir dos itens anteriores construímos uma função
is_phone_number
isso leva umSTRING
e retorna umBOOLEAN
que indica se a string especificada representa um número de telefone válido.Uma solução simples seria escrevermake (tel: STRING) require is_phone_number (tel) ...
e tem um recurso
is_phone_number
na aulaDEPARTMENT
em si.Mas isso nos impede de verificar se a string especificada representa um número de telefone antes de chamar este procedimento de criação.Então faz sentido mudaris_phone_number
para a aulaPHONE_NUMBER_VALIDATOR
aquela aulaDEPARTMENT
herdará.Da mesma forma, sePHONE_NUMBER
precisa validar a string em relação a regras especificadas, ela pode herdarPHONE_NUMBER_VALIDATOR
e reutilizar o recursois_phone_number
.
Outras dicas
Halikal realmente resolveu isso, mas não compartilhou até agora...
Isso funciona no eiffelStudio 6.2 (nota - este é o gobo)
http://se.inf.ethz.ch/old/people/leitner/gobo_guidelines/naming_conventions.html
Um número de telefone válido consiste em um dos seguintes:
- oito dígitos, o primeiro dos quais é diferente de zero
- um zero líder, um único código de área de dígitos diferentes de zero e depois oito dígitos, o primeiro dos quais é diferente de zero
- um líder + seguido por um código de dois dígitos do país, depois um único código de área de dígitos diferentes de zero e depois oito dígitos, o primeiro dos quais é diferente de zero
Quaisquer espaços incorporados devem ser ignorados ao validar um número de telefone.
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