Как бы я изменил это регулярное выражение для извлечения левой и правой частей почтового индекса Великобритании? - PullRequest
2 голосов
/ 26 марта 2009

У меня есть регулярное выражение, которое работает для проверки почтовых индексов Великобритании, но теперь я хотел бы извлечь составные части кода, и я запутался. Для тех, кто не знает примеров почтовых индексов Великобритании: «WC1 1AA», «WC11 1AA» и «M1 1AA».

Регулярное выражение ниже (извинения за форматирование) обрабатывает отсутствие пробела (это бит \s{0,}) между левой и правой частями и все еще проверяет (что здорово).

(?:(?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?\s{0,}\d[A-Z]{2})

Я бы хотел иметь возможность извлечь левую и правую стороны сейчас, и я знаю, что для этого используются скобки, но там уже есть скобки, и спецификацию регулярного выражения нелегко прочитать. Поэтому я думаю, что эти скобки нуждаются в замене. Может ли кто-нибудь помочь мне переделать мои скобки?

Я вижу, что другие люди могут найти это регулярное выражение, поэтому, пожалуйста, не стесняйтесь использовать его для проверки почтовых адресов в Великобритании.

Ответы [ 3 ]

5 голосов
/ 26 марта 2009

На самом деле для извлечения используются скобки, а не скобки. Конструкции (?: В вашем выражении - это то, как вы препятствуете скобкам выполнять извлечение. Вы бы хотели:

(?:((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?)\s{0,}(\d[A-Z]{2}))

Кстати, я бы тоже сделал это изменение:

(?:((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?)\s*(\d[A-Z]{2}))

потому что \ s {0,} - глупый способ написать \ s *.

4 голосов
/ 26 марта 2009

Кроме того, я бы рекомендовал не пытаться так тщательно проверять почтовый индекс. Список допустимых почтовых индексов может измениться, поэтому вам придется сохранять выражение каждый раз, когда Почтовое отделение обновляет PAF.

Вам также не хватает некоторых «специальных почтовых индексов», таких как BFPO, GIR, негеографических почтовых индексов и заморских территорий. См. wiki для обзора того, с чем вам, возможно, придется иметь дело.

В целом для большинства целей проверка «выглядит ли это правдоподобно?» Лучше, чем пытаться полностью ее зафиксировать. Нет ничего хуже, чем говорить клиентам, что они не могут пользоваться вашим сервисом, потому что их адрес не существует.

1 голос
/ 26 марта 2009

При работе с большим регулярным выражением, подобным этому, вы должны использовать опцию /x (я думаю, что она называется RegexOptions.IgnorePatternWhitespace в C #). (? :) не захватывает, поэтому все, что вам нужно сделать, это поместить () вокруг частей, которые вы хотите. Еще одно преимущество опции /x заключается в том, что вы можете комментировать регулярное выражение комментариями в конце строки (они начинаются с #). Вам также может понадобиться быть осторожным с \ d и \ s. Они могут соответствовать больше, чем вы ожидаете (\s соответствует всем пробелам, а не только пробелам и, по крайней мере, в Perl 5.8 и более поздних версиях, \d соответствует всем символам UNICODE, а не только [0-9])

Regex exp = new Regex(@"
    (?:
        ( #capture first part
            (?:
                A[BL]        | B[ABDHLNRST]? | C[ABFHMORTVW]      |
                D[ADEGHLNTY] | E[CHNX]?      | F[KY]              |
                G[LUY]?      | H[ADGPRSUX]   | I[GMPV]            |
                JE           | K[ATWY]       | L[ADELNSU]?        |
                M[EKL]?      | N[EGNPRW]?    | O[LX]              |
                P[AEHLOR]    | R[GHM]        | S[AEGKLMNOPRSTWY]? |
                T[ADFNQRSW]  | UB            | W[ACDFNRSV]?       |
                YO           | ZE
            )
            \d
            (?:
                \d | [A-Z]
            )?
        ) #end capture of first part
        \s{0,}
        ( #capture second part
            \d[A-Z]{2}
        ) #end capture of second part
    )",
    RegexOptions.IgnorePatternWhitespace
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...