Ограничение строки сложным регулярным выражением - PullRequest
1 голос
/ 18 марта 2012

Я работаю над набором классов валидации и в настоящее время создаю плагины для применения различных правил валидации. Я создал следующий класс для проверки почтового индекса в Великобритании:

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 :: PATTERN, было получено из данных, приведенных в статье Википедии о британских почтовых индексах . Тем не менее, данное регулярное выражение обнаруживает допустимые строки почтового индекса, содержащиеся в больших блоках текста. Я хочу, чтобы он точно совпадал только с действительным почтовым индексом, за исключением предшествующих и следующих символов. Поэтому (SW1A 0AA) следует передать как действительный, а (foobarSW1A 0AA) - нет.

Я добавил якоря к регулярному выражению (^ в начале и $ в конце), чтобы заставить его принимать только строку, состоящую только из почтового индекса, в качестве допустимого. Тем не менее, класс по-прежнему передает почтовые индексы со строками-заполнителями и / или строками без почтовых индексов.

Что я делаю не так? Я думал, что добавления якорей будет достаточно, чтобы получить поведение, которое я хотел.

1 Ответ

3 голосов
/ 18 марта 2012

Добавьте якоря как:

^(?:regex)$

^foo|bar$ - это не то же самое, что ^(?:foo|bar)$.

Также следует использовать \z вместо $.$ допускает необязательный разрыв строки в конце строки, тогда как \z - строгое совпадение конца строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...