简体   繁体   English

Eiffel正则表达式验证

[英]Eiffel regular expression validation

How do you create a regular expression for a certain string? 如何为某个字符串创建正则表达式? And can you do it in the Assertion (precondition part of the code)? 你可以在断言(代码的前提条件部分)中做到吗?

I've been google-ing around but couldn't get anything convincing. 我一直在谷歌周围,但无法得到任何令人信服的东西。

The question is like this: 问题是这样的:

Add a precondition to the DEPARTMENT (the class that we're working on) creation procedure that ensures that the phone number is valid. 向DEPARTMENT(我们正在处理的类)创建过程添加前提条件,以确保电话号码有效。 There are three possible valid phone number formats. 有三种可能的有效电话号码格式。 A valid phone number consists of one of: 有效的电话号码包括以下其中一项:

  • eight digits, the first of which is non-zero 八位数,第一位是非零
  • a leading zero, a single non-zero digit area code, and then eight digits, the first of which is non-zero 一个前导零,一个非零数字区号,然后是八个数字,第一个是非零
  • a leading '+', followed by a two digit country code, then a single non-zero digit area code, and then eight digits, the first of which is non-zero 一个前导'+',后跟一个两位数的国家代码,然后是一个非零数字区号,然后是八位数,其中第一个是非零

Any embedded spaces are to be ignored when validating a phone number. 验证电话号码时,将忽略任何嵌入的空格。

It is acceptable, but not required, to add a PHONE_NUMBER class to the system as part of solving this problem. 作为解决此问题的一部分,将PHONE_NUMBER类添加到系统是可接受的,但不是必需的。

There are several different questions to be answered: 有几个不同的问题需要回答:

  1. How to check if a given string matches a specified regular expression in Eiffel? 如何检查给定字符串是否与Eiffel中的指定正则表达式匹配? One can use a class RX_PCRE_MATCHER from the Gobo library. 可以使用Gobo库中的类RX_PCRE_MATCHER The feature compile allows setting the required regular expression and the feature recognizes allows testing if the string matches it. 功能compile允许设置所需的正则表达式,并且功能recognizes允许测试字符串是否匹配。

  2. How to write a regular expression for the given phone number specification? 如何为给定的电话号码规范编写正则表达式? Something like "(|0[1-9]|\\+[0-9]{2}[1-9])[1-9][0-8]{7}" should do though I have not checked it. "(|0[1-9]|\\+[0-9]{2}[1-9])[1-9][0-8]{7}"应该做但我还没检查过。 It's possible to take intermediate white spaces into account in the regular expression itself, but it's much easier to get rid of them before passing to the regular expression matcher by applying prune_all (' ') on the input string. 可以在正则表达式本身中考虑中间空白区域,但是在通过在输入字符串上应用prune_all (' ')传递给正则表达式匹配器之前更容易去掉它们。

  3. How to add a precondition to a creation procedure to verify that the argument satisfies it? 如何在创建过程中添加前置条件以验证参数是否满足它? Let's assume that from the previous items we constructed a function is_phone_number that takes a STRING and returns a BOOLEAN that indicates if the specified string represents a valid phone number. 让我们假设从前面的项目中我们构造了一个函数is_phone_number ,它接受一个STRING并返回一个BOOLEAN ,指示指定的字符串是否代表一个有效的电话号码。 A straightforward solution would be to write 一个简单的解决方案是写

     make (tel: STRING) require is_phone_number (tel) ... 

    and have a feature is_phone_number in the class DEPARTMENT itself. 并在类DEPARTMENT本身中有一个功能is_phone_number But this prevents us from checking if the specified string represents a phone number before calling this creation procedure. 但这会阻止我们在调用此创建过程之前检查指定的字符串是否代表电话号码。 So it makes sense to move is_phone_number to the class PHONE_NUMBER_VALIDATOR that class DEPARTMENT will inherit. 因此,将is_phone_number移动到类DEPARTMENT将继承的类PHONE_NUMBER_VALIDATOR是有意义的。 Similarly, if PHONE_NUMBER needs to validate the string against specified rules, it can inherit PHONE_NUMBER_VALIDATOR and reuse the feature is_phone_number . 同样,如果PHONE_NUMBER需要根据指定的规则验证字符串,它可以继承PHONE_NUMBER_VALIDATOR is_phone_number用功能is_phone_number

Halikal actually worked this one out, but dudn't share until now ... Halikal实际上已经解决了这个问题,但直到现在还没有分享......

This works in eiffelStudio 6.2 (note - this is gobo) 这适用于eiffelStudio 6.2(注意 - 这是图案片)

http://se.inf.ethz.ch/old/people/leitner/gobo_guidelines/naming_conventions.html http://se.inf.ethz.ch/old/people/leitner/gobo_guidelines/naming_conventions.html

A valid phone number consists of one of: 有效的电话号码包括以下其中一项:

  • eight digits, the first of which is non-zero 八位数,第一位是非零
  • a leading zero, a single non-zero digit area code, and then eight digits, the first of which is non-zero 一个前导零,一个非零数字区号,然后是八个数字,第一个是非零
  • a leading + followed by a two digit country code, then a single non-zero digit area code, and then eight digits, the first of which is non-zero 一个前导+后跟一个两位数的国家代码,然后是一个非零数字区号,然后是八位数,其中第一个是非零

Any embedded spaces are to be ignored when validating a phone number. 验证电话号码时,将忽略任何嵌入的空格。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM