2012-03-18 97 views
1

我正在處理一組驗證類,並且正在構建應用各種驗證規則的插件。我已經建立了下面的類用於驗證英國郵政編碼:限制複雜的正則表達式

class PostcodeUk extends abstr\Prop implements iface\Prop 
{ 
    const 

     /** 
     * Defines the regular expression against which to test postal code 
     * 
     * @see http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation UK postal code validation rules on Wikipedia 
     */ 
     PATTERN = '/^(GIR 0AA)|(((A[BL]|B[ABDHLNRSTX]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTY]?|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)[1-9]?[0-9]|((E|N|NW|SE|SW|W)1|EC[1-4]|WC[12])[A-HJKMNPR-Y]|(SW|W)([2-9]|[1-9][0-9])|EC[1-9][0-9]) [0-9][ABD-HJLNP-UW-Z]{2})$/'; 

    /** 
    * 
    * @return bool True if valid 
    * @throws \InvalidArgumentException 
    */ 
    public function isValid() 
    { 
     $valid = false; 
     $data = $this -> getData(); 

     switch (gettype ($data)) 
     { 
      case 'NULL'  : 
       $valid = true; 
      break; 
      case 'string' : 
       $valid = preg_match (static::PATTERN, $data) > 0; 
      break; 
      default   : 
       throw new \InvalidArgumentException (__CLASS__ . ': This property cannot be applied to data of type ' . gettype ($data)); 
      break; 
     } 

     return ($valid); 
    } 
} 

在PostcodeUk ::模式中定義的正則表達式是從衍生於Wikipedia's article on UK postcodes給出。但是,給定的正則表達式會檢測更大塊文本中包含的有效郵政編碼字符串。我希望它只能匹配有效的郵政編碼,不包括前面和後面的字符。所以(SW1A 0AA)應該通過有效,但(foobarSW1A 0AA)不應該。

我在正則表達式中添加了錨(^在開始處和$在結尾處)試圖強制它只接受一個只包含郵編的字符串作爲有效的字符串。但是,該類仍然通過包含填充和/或非郵政編碼字符串的郵政編碼。

我在做什麼錯?我認爲添加錨點足以獲得我想要的行爲。

回答

3

添加錨點爲:

^(?:regex)$ 

^foo|bar$是不一樣的^(?:foo|bar)$。您還應該使用\z而不是$$允許在字符串結尾處有一個可選的換行符,而\z是字符串匹配的嚴格結尾。

+0

+1找到明顯的問題。 – xfix 2012-03-18 09:16:06

+0

對不起,只需要一點澄清。你的意思是'/ ^(?:(GIR 0AA)|(等等等等等)等等)$'? (好的,編輯更清楚一點,謝謝) – GordonM 2012-03-18 09:16:44

+0

@GordonM,是的,但是使用'\ z'。 – Qtax 2012-03-18 09:18:48