Eiffel正则表达式验证

时间:2011-03-26 12:16:33

标签: regex eiffel

如何为某个字符串创建正则表达式?你能在断言(代码的前提条件部分)中做到吗?

我一直在谷歌周围但却无法获得任何令人信服的信息。

问题是这样的:

为DEPARTMENT(我们正在处理的类)创建程序添加前提条件,以确保电话号码有效。有三种可能的有效电话号码格式。有效的电话号码包含以下其中一项:

  • 八位数,第一位是非零
  • 一个前导零,一个非零数字区号,然后八个数字,第一个 这是非零的
  • 前导'+',后跟两位数国家代码,然后是一个非零数字 区号,然后是八位数,第一位是非零

验证电话号码时,将忽略任何嵌入的空格。

将PHONE_NUMBER类作为其一部分添加到系统中是可接受的,但不是必需的 解决这个问题。

2 个答案:

答案 0 :(得分:2)

有几个不同的问题需要回答:

  1. 如何检查给定字符串是否与Eiffel中指定的正则表达式匹配?可以使用Gobo库中的类RX_PCRE_MATCHER。功能compile允许设置所需的正则表达式,功能recognizes允许测试字符串是否匹配。

  2. 如何为给定的电话号码规范编写正则表达式?像"(|0[1-9]|\+[0-9]{2}[1-9])[1-9][0-8]{7}"这样的东西应该可以做,虽然我还没有检查过。在正则表达式本身中可以考虑中间空白区域,但是在传递给正则表达式匹配器之前通过在输入字符串上应用prune_all (' ')来更容易去掉它们。

  3. 如何在创建过程中添加前置条件以验证参数是否满足它?让我们假设从前面的项目中我们构造了一个函数is_phone_number,它接受​​STRING并返回BOOLEAN,表示指定的字符串是否代表有效的电话号码。一个简单的解决方案就是写

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

    并在类is_phone_number中拥有一个功能DEPARTMENT。但这会阻止我们在调用此创建过程之前检查指定的字符串是否代表电话号码。因此,将is_phone_number移动到类PHONE_NUMBER_VALIDATOR将继承的类DEPARTMENT是有意义的。同样,如果PHONE_NUMBER需要根据指定规则验证字符串,则可以继承PHONE_NUMBER_VALIDATOR并重复使用该功能is_phone_number

答案 1 :(得分:2)

Halikal实际上已经解决了这个问题,但直到现在还没有分享......

这适用于eiffelStudio 6.2(注意 - 这是图案片)

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

有效的电话号码包含以下其中一项:

  • 八位数,第一位是非零
  • 一个前导零,一个非零数字区号,   然后是八位数,第一位是非零
  • 领先+后跟两位数的国家/地区代码,   那么一个非零数字区号,然后八位数,   第一个是非零的

验证电话号码时,将忽略任何嵌入的空格。

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