RegEx untuk mencocokkan Kode Pos Inggris

186

Saya mengejar regex yang akan memvalidasi kode pos UK lengkap yang kompleks hanya dalam string input. Semua bentuk kode pos yang tidak umum harus dicakup sebagaimana biasa. Misalnya:

Cocok

  • CW3 9SS
  • SE5 0EG
  • SE50EG
  • se5 0eg
  • WC2H 7LT

Tidak cocok

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Bagaimana saya mengatasi masalah ini?

Kieran Benton
sumber
2
@axrwkr yang sepertinya tidak membantu
Kieran Benton
8
Validasi Kode Pos Inggris - JavaScript dan PHP Saya tidak bisa mendapatkan jawaban yang diterima untuk mencocokkan kode pos yang valid tapi saya menemukan ini dan cocok dengan kode pos yang valid. Untuk validasi sisi klien, versi JavaScript dapat digunakan apa adanya, untuk validasi sisi server, menulis ulang JavaScript sebagai C # cukup mudah. Bahkan memformat ulang kode pos untuk memiliki ruang, jadi jika Anda memasukkan kode pos sebagai W1A1AA, selain memvalidasi, kode pos itu akan diformat ulang menjadi W1A 1AA. Bahkan berurusan dengan kode pos yang tidak biasa di berbagai wilayah Inggris.
2
Tautan yang diberikan tidak berfungsi untuk format "AA1A 1AA". Referensi: dhl.com.tw/content/dam/downloads/tw/express/forms/…
Anthony Scaife
1
Jika Anda hanya ingin memvalidasi kode pos, kami menawarkan titik akhir REST API validasi gratis (daftar diperlukan) - developers.alliescomputing.com/postcoder-web-api/address-lookup/…
Stephen Keable
1
Pertanyaan bagus. Saya pikir itu akan layak termasuk kode pos Manchester pusat seperti "M1 3HZ" dalam daftar contoh-contoh tidak biasa yang perlu dicocokkan. Banyak orang tidak mengetahui kombinasi angka 1 huruf 1.
Martin Joiner

Jawaban:

208

Saya akan merekomendasikan untuk melihat Standar Data Pemerintah Inggris untuk kode pos [tautan sekarang mati; arsip XML , lihat Wikipedia untuk diskusi]. Ada deskripsi singkat tentang data dan skema xml terlampir menyediakan ekspresi reguler. Ini mungkin bukan apa yang Anda inginkan tetapi akan menjadi titik awal yang baik. RegEx sedikit berbeda dari XML, karena karakter P di posisi ketiga dalam format A9A 9AA diizinkan oleh definisi yang diberikan.

RegEx yang disediakan oleh Pemerintah Inggris adalah:

([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\s?[0-9][A-Za-z]{2})

Seperti yang ditunjukkan pada diskusi Wikipedia, ini akan memungkinkan beberapa kode pos non-nyata (misalnya yang memulai AA, ZY) dan mereka memberikan tes yang lebih ketat yang bisa Anda coba.

Brian Campbell
sumber
52
Dan reg itu dengan spasi putih opsional antara dua segmen (GIR 0AA) | (([[AZ- [QVX]] [0-9] [0-9]?) | (([AZ- [QVX]] [AZ- [IJZ]] [0-9] [0-9]?) | (([AZ- [QVX]] [0-9] [A-HJKSTUW]) | ([AZ- [QVX]] [ AZ- [IJZ]] [0-9] [ABEHMNPRVWXY])))))? [0-9] [AZ- [CIKMOV]] {2})
gb2d
7
Mungkin ide yang baik untuk membawa regex yang sebenarnya ke jawabannya, karena halaman tampaknya kadaluwarsa setiap tahun ...
pauloya
7
Perhatikan regex ini untuk Skema XML, yang, jelas, sedikit berbeda dari rasa regex lainnya
artbristol
6
Saya tidak bisa mengaktifkan ini di JavaScript. Apakah hanya bekerja dengan mesin regex tertentu?
NickG
12
Sebenarnya mereka mengubahnya: Transfer Data Massal :^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$
wieczorek1990
85

Sepertinya kita akan menggunakan ^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$ , yang merupakan versi sedikit dimodifikasi yang disarankan oleh Minglis di atas.

Namun, kami harus menyelidiki dengan tepat apa aturannya, karena berbagai solusi yang tercantum di atas tampaknya menerapkan aturan berbeda tentang surat mana yang diizinkan.

Setelah beberapa penelitian, kami telah menemukan beberapa informasi lebih lanjut. Rupanya halaman di 'govtalk.gov.uk' mengarahkan Anda ke spesifikasi kode pos govtalk-postcodes . Ini menunjuk ke skema XML di XML Schema yang menyediakan pernyataan 'pseudo regex' dari aturan kode pos.

Kami telah mengambilnya dan mengerjakannya sedikit untuk memberi kami ungkapan berikut:

^((GIR &0AA)|((([A-PR-UWYZ][A-HK-Y]?[0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]))) &[0-9][ABD-HJLNP-UW-Z]{2}))$

Ini menjadikan spasi opsional, tetapi membatasi Anda ke satu spasi (ganti '&' dengan '{0,} untuk spasi tak terbatas). Itu mengasumsikan semua teks harus huruf besar.

Jika Anda ingin mengizinkan huruf kecil, dengan sejumlah spasi, gunakan:

^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

Ini tidak mencakup wilayah luar negeri dan hanya memberlakukan format, BUKAN keberadaan berbagai wilayah. Ini didasarkan pada aturan berikut:

Dapat menerima format berikut:

  • “GIR 0AA”
  • A9 9ZZ
  • A99 9ZZ
  • AB9 9ZZ
  • AB99 9ZZ
  • A9C 9ZZ
  • 9ZZ AD9E

Dimana:

  • 9 dapat berupa angka satu digit.
  • A dapat berupa huruf apa saja kecuali untuk Q, V atau X.
  • B dapat berupa huruf apa pun kecuali untuk I, J atau Z.
  • C dapat berupa huruf apa pun kecuali untuk I, L, M, N, O, P, Q, R, V, X, Y atau Z.
  • D dapat berupa huruf apa pun kecuali untuk I, J atau Z.
  • E dapat berupa A, B, E, H, M, N, P, R, V, W, X atau Y.
  • Z dapat berupa huruf apa pun kecuali untuk C, I, K, M, O atau V.

Semoga sukses

Colin

Colin
sumber
2
Jawaban yang bagus, saya menambahkan di luar negeri^(([gG][iI][rR] {0,}0[aA]{2})|(([aA][sS][cC][nN]|[sS][tT][hH][lL]|[tT][dD][cC][uU]|[bB][bB][nN][dD]|[bB][iI][qQ][qQ]|[fF][iI][qQ][qQ]|[pP][cC][rR][nN]|[sS][iI][qQ][qQ]|[iT][kK][cC][aA]) {0,}1[zZ]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yxA-HK-XY]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$
David Bradshaw
Mengapa {0,}memilih bukan *untuk ruang opsional tanpa batas?
Kode Hewan
76

Saya baru-baru diposting jawaban untuk pertanyaan ini pada kode pos Inggris untuk bahasa R . Saya menemukan bahwa pola regex Pemerintah Inggris salah dan gagal dengan benar memvalidasi beberapa kode pos. Sayangnya, banyak jawaban di sini didasarkan pada pola yang salah ini.

Saya akan menguraikan beberapa masalah di bawah ini dan memberikan ekspresi reguler yang direvisi yang benar - benar berfungsi.


Catatan

Jawaban saya (dan ekspresi reguler secara umum):

  • Hanya memvalidasi format kode pos .
  • Tidak memastikan bahwa kode pos ada secara sah .
    • Untuk ini, gunakan API yang sesuai! Lihat jawaban Ben untuk info lebih lanjut.

Jika Anda tidak peduli dengan regex yang buruk dan hanya ingin melewatkan jawaban, gulir ke bawah ke bagian Jawab .

Regex Buruk

Ekspresi reguler di bagian ini tidak boleh digunakan.

Ini adalah regex yang gagal yang disediakan oleh pemerintah Inggris untuk pengembang (tidak yakin berapa lama tautan ini akan naik, tetapi Anda dapat melihatnya di dokumentasi Transfer Data Massal mereka ):

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$

Masalah

Masalah 1 - Salin / Tempel

Lihat regex yang digunakan di sini .

Seperti yang mungkin dilakukan banyak pengembang, mereka menyalin / menempelkan kode (terutama ekspresi reguler) dan menempelnya agar mereka berfungsi. Walaupun ini bagus secara teori, ia gagal dalam kasus khusus ini karena menyalin / menempel dari dokumen ini sebenarnya mengubah salah satu karakter (spasi) menjadi karakter baris baru seperti yang ditunjukkan di bawah ini:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))
[0-9][A-Za-z]{2})$

Hal pertama yang akan dilakukan kebanyakan pengembang adalah menghapus baris baru tanpa berpikir dua kali. Sekarang regex tidak akan cocok dengan kode pos dengan spasi di dalamnya (selainGIR 0AA kode pos).

Untuk memperbaiki masalah ini, karakter baris baru harus diganti dengan karakter spasi:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                                                                                     ^

Masalah 2 - Batas

Lihat regex yang digunakan di sini .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
^^                     ^ ^                                                                                                                                            ^^

Kode pos regex secara tidak patut jangkar regex. Siapa pun yang menggunakan regex ini untuk memvalidasi kode pos mungkin akan terkejut jika nilainya sepertifooA11 1AA melewati. Itu karena mereka telah meletakkan awal opsi pertama dan akhir opsi kedua (terlepas dari satu sama lain), sebagaimana ditunjukkan dalam regex di atas.

Ini artinya ^(menegaskan posisi di awal baris) hanya berfungsi pada opsi pertama ([Gg][Ii][Rr] 0[Aa]{2}), jadi opsi kedua akan memvalidasi string apa pun yang berakhir dengan kode pos (terlepas dari apa yang datang sebelumnya).

Demikian pula, opsi pertama tidak berlabuh ke akhir baris $, jadi GIR 0AAfoojuga diterima.

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$

Untuk memperbaiki masalah ini, kedua opsi harus dibungkus dalam kelompok lain (atau kelompok yang tidak menangkap) dan jangkar ditempatkan di sekitarnya:

^(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$
^^                                                                                                                                                                      ^^

Masalah 3 - Set Karakter Tidak Benar

Lihat regex yang digunakan di sini .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                       ^^

Regex tidak ada di -sini untuk menunjukkan serangkaian karakter. Seperti berdiri, jika kode pos dalam format ANA NAA(di mana Amewakili huruf dan Nmewakili angka), dan itu dimulai dengan apa pun selain AatauZ , itu akan gagal.

Itu berarti akan cocok A1A 1AAdan Z1A 1AA, tetapi tidak B1A 1AA.

Untuk memperbaiki masalah ini, karakter -harus ditempatkan di antara Adan Zdi set karakter masing-masing:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                        ^

Masalah 4 - Set Karakter Opsional Salah

Lihat regex yang digunakan di sini .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                                                                        ^

Saya bersumpah mereka bahkan tidak menguji hal ini sebelum mempublikasikannya di web. Mereka membuat set karakter yang salah menjadi opsional. Mereka membuat [0-9]opsi di sub-opsi keempat opsi 2 (grup 9). Ini memungkinkan regex untuk mencocokkan kode pos yang salah diformat seperti AAA 1AA.

Untuk memperbaiki masalah ini, buat kelas karakter selanjutnya sebagai opsional (dan kemudian buat pasangan yang [0-9]cocok persis sekali):

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?)))) [0-9][A-Za-z]{2})$
                                                                                                                                                ^

Masalah 5 - Kinerja

Kinerja pada regex ini sangat buruk. Pertama, mereka menempatkan opsi pola yang paling tidak cocok untuk dicocokkan GIR 0AAdi awal. Berapa banyak pengguna yang mungkin memiliki kode pos ini dibandingkan dengan kode pos lainnya; mungkin tidak pernah? Ini berarti setiap kali regex digunakan, ia harus menghabiskan opsi ini terlebih dahulu sebelum melanjutkan ke opsi berikutnya. Untuk melihat bagaimana kinerja terpengaruh, periksa jumlah langkah yang diambil regex asli (35) terhadap regex yang sama setelah membalik opsi (22).

Masalah kedua dengan kinerja adalah karena cara seluruh regex terstruktur. Tidak ada gunanya menelusuri kembali setiap opsi jika ada yang gagal. Cara regex saat ini disusun dapat sangat disederhanakan. Saya memberikan perbaikan untuk ini di bagian Jawaban .

Masalah 6 - Spasi

Lihat regex yang digunakan di sini

Ini mungkin tidak dianggap sebagai masalah , tetapi itu menimbulkan kekhawatiran bagi sebagian besar pengembang. Spasi di regex tidak opsional, yang berarti pengguna memasukkan kode pos mereka harus menempatkan spasi di kode pos. Ini adalah perbaikan yang mudah dengan hanya menambahkan ?setelah spasi untuk menjadikannya opsional. Lihat bagian Jawaban untuk perbaikan.


Menjawab

1. Memperbaiki Regex Pemerintah Inggris

Memperbaiki semua masalah yang diuraikan di bagian Masalah dan menyederhanakan pola menghasilkan pola berikut, lebih pendek, lebih ringkas. Kami juga dapat menghapus sebagian besar grup karena kami memvalidasi kode pos secara keseluruhan (bukan bagian individual):

Lihat regex yang digunakan di sini

^([A-Za-z][A-Ha-hJ-Yj-y]?[0-9][A-Za-z0-9]? ?[0-9][A-Za-z]{2}|[Gg][Ii][Rr] ?0[Aa]{2})$

Ini lebih lanjut dapat dipersingkat dengan menghapus semua rentang dari salah satu kasus (huruf besar atau kecil) dan menggunakan bendera case-insensitive. Catatan : Beberapa bahasa tidak memiliki satu, jadi gunakan yang lebih panjang di atas. Setiap bahasa mengimplementasikan flag ketidaksensitifan kasus secara berbeda.

Lihat regex yang digunakan di sini .

^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$

Lebih pendek lagi menggantikan [0-9]dengan \d(jika mesin regex Anda mendukungnya):

Lihat regex yang digunakan di sini .

^([A-Z][A-HJ-Y]?\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$

2. Pola Sederhana

Tanpa memastikan karakter alfabet tertentu, berikut ini dapat digunakan (perlu diingat penyederhanaan dari 1. Memperbaiki Regex Pemerintah Inggris juga telah diterapkan di sini):

Lihat regex yang digunakan di sini .

^([A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$

Dan lebih jauh lagi jika Anda tidak peduli dengan kasus khusus GIR 0AA:

^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$

3. Pola rumit

Saya tidak akan menyarankan verifikasi kode pos yang berlebih karena Area, Distrik, dan Sub-distrik baru dapat muncul kapan saja. Apa yang akan saya sarankan berpotensi melakukan, ditambahkan dukungan untuk tepi-kasus. Beberapa kasus khusus ada dan diuraikan dalam artikel Wikipedia ini .

Berikut adalah regex kompleks yang mencakup sub-bagian 3. (3.1, 3.2, 3.3).

Sehubungan dengan pola dalam 1. Memperbaiki Regex Pemerintah Inggris :

Lihat regex yang digunakan di sini

^(([A-Z][A-HJ-Y]?\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

Dan terkait dengan 2. Pola Sederhana :

Lihat regex yang digunakan di sini

^(([A-Z]{1,2}\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

3.1 Wilayah Luar Negeri Britania

Artikel Wikipedia saat ini menyatakan (beberapa format sedikit disederhanakan):

  • AI-1111: Anguila
  • ASCN 1ZZ: Pulau Ascension
  • STHL 1ZZ: Saint Helena
  • TDCU 1ZZ: Tristan da Cunha
  • BBND 1ZZ: Wilayah Samudra Hindia Britania
  • BIQQ 1ZZ: Wilayah Antartika Britania
  • FIQQ 1ZZ: Kepulauan Falkland
  • GX11 1ZZ: Gibraltar
  • PCRN 1ZZ: Kepulauan Pitcairn
  • SIQQ 1ZZ: Georgia Selatan dan Kepulauan Sandwich Selatan
  • TKCA 1ZZ: Kepulauan Turks dan Caicos
  • BFPO 11: Akrotiri dan Dhekelia
  • ZZ 11& GE CX: Bermuda (sesuai dengan dokumen ini )
  • KY1-1111: Kepulauan Cayman (menurut dokumen ini )
  • VG1111: Kepulauan Virgin Britania Raya (menurut dokumen ini )
  • MSR 1111: Montserrat (menurut dokumen ini )

Regex yang mencakup semua untuk mencocokkan hanya Wilayah Luar Negeri Inggris yang akan terlihat seperti ini:

Lihat regex yang digunakan di sini .

^((ASCN|STHL|TDCU|BBND|[BFS]IQQ|GX\d{2}|PCRN|TKCA) ?\d[A-Z]{2}|(KY\d|MSR|VG|AI)[ -]?\d{4}|(BFPO|[A-Z]{2}) ?\d{2}|GE ?CX)$

3.2 Kantor Pos Pasukan Inggris

Meskipun mereka baru-baru ini mengubahnya untuk menyelaraskan dengan sistem kode pos Inggris lebih baik BF#(di mana #mewakili angka), mereka dianggap sebagai kode pos alternatif opsional . Kode pos ini mengikuti (ed) format BFPO, diikuti oleh 1-4 digit:

Lihat regex yang digunakan di sini

^BFPO ?\d{1,4}$

3.3 Santa?

Ada kasus khusus lain dengan Santa (seperti yang disebutkan dalam jawaban lain): SAN TA1adalah kode pos yang valid. Regex untuk ini sangat sederhana:

^SAN ?TA1$
lihat roda
sumber
4
Pola yang disederhanakan adalah pilihan yang sangat bagus untuk digunakan. Saya menemukan yang terbaik untuk tidak terlalu membatasi dengan regex karena Anda kemudian perlu memastikan itu diperbarui dengan perubahan atau Anda dapat memiliki pengguna yang sangat marah. Saya merasa lebih baik untuk mencocokkan secara longgar dengan regex yang disederhanakan untuk menghilangkan kesalahan yang jelas dan kemudian menerapkan pemeriksaan lebih lanjut seperti pencarian alamat (atau email konfirmasi dalam kasus email regex) untuk mengkonfirmasi validitas.
James Coyle
2
Analisis yang sangat baik dan menyeluruh.
Steve
1
Jawaban cemerlang pada banyak tingkatan. Pada akhirnya, saya menggunakan pola kedua Anda yang disederhanakan. Karena saya benar-benar memiliki DB dengan semua kode pos UK, saya hanya perlu pass pertama untuk melihat apakah string alamat berpotensi berisi kode pos yang valid, jadi saya tidak peduli tentang false positive (karena pencarian yang sebenarnya akan membasmi mereka) , tapi saya peduli negatif palsu. Dan kecepatan juga penting.
John Powell
Ada begitu banyak masalah dengan sistem kode pos UK, secara nyata dibuat oleh komite sebelum era komputer, tetapi masalah panjang variabel dan ruang adalah salah satu yang paling merusak. Saya telah melihat segala macam kengerian, termasuk padding kode pos seperti E1 5JX ke E1 5JX, yaitu, dengan tiga spasi, sehingga sejajar dengan SW18 5HA di Excel (masukkan perangkat lunak yang tidak sesuai pilihan untuk mengelola alamat). Satu-satunya solusi yang waras, IMHO, adalah menghapus semua spasi, sehingga kode posnya adalah string tunggal sebelum mendekati Elastis, Solr, Postgres, dll.
John Powell
45

Tidak ada yang namanya ekspresi reguler kode pos UK komprehensif yang mampu memvalidasi kode pos. Anda dapat memeriksa bahwa kode pos dalam format yang benar menggunakan ekspresi reguler; tidak benar-benar ada.

Kode pos sewenang-wenang kompleks dan terus berubah. Misalnya, outcode W1tidak, dan mungkin tidak pernah, memiliki setiap angka antara 1 dan 99, untuk setiap area kode pos.

Anda tidak bisa berharap apa yang ada saat ini benar selamanya. Sebagai contoh, pada tahun 1990, Kantor Pos memutuskan bahwa Aberdeen menjadi agak ramai. Mereka menambahkan 0 di akhir AB1-5 sehingga AB10-50 dan kemudian membuat sejumlah kode pos di antaranya.

Setiap kali jalan baru dibangun, kode pos baru dibuat. Itu bagian dari proses untuk mendapatkan izin untuk membangun; otoritas lokal berkewajiban untuk memperbaharui ini dengan Kantor Pos (bukan berarti mereka semua melakukannya).

Selain itu, seperti dicatat oleh sejumlah pengguna lain, ada kode pos khusus seperti Girobank, GIR 0AA, dan satu untuk surat ke Santa, SAN TA1 - Anda mungkin tidak ingin memposting apa pun di sana tetapi tampaknya tidak dicakup oleh jawaban lain.

Lalu, ada kode pos BFPO, yang sekarang berubah ke format yang lebih standar . Kedua format akan valid. Terakhir, ada sumber teritori Wikipedia di luar negeri .

+ ---------- + -------------------------------------- -------- +
| Kode pos | Lokasi |
+ ---------- + -------------------------------------- -------- +
| AI-2640 | Anguilla |
| ASCN 1ZZ | Pulau Ascension |
| STHL 1ZZ | Saint Helena |
| TDCU 1ZZ | Tristan da Cunha |
| BBND 1ZZ | Wilayah Samudra Hindia Britania |
| BIQQ 1ZZ | Wilayah Antartika Britania |
| FIQQ 1ZZ | Kepulauan Falkland |
| GX11 1AA | Gibraltar |
| PCRN 1ZZ | Kepulauan Pitcairn |
| SIQQ 1ZZ | Georgia Selatan dan Kepulauan Sandwich Selatan |
| TKCA 1ZZ | Kepulauan Turks dan Caicos |
+ ---------- + -------------------------------------- -------- +

Selanjutnya, Anda harus mempertimbangkan bahwa Inggris "mengekspor" sistem kode posnya ke banyak tempat di dunia. Apa pun yang memvalidasi kode pos "Inggris" juga akan memvalidasi kode pos dari sejumlah negara lain.

Jika Anda ingin memvalidasi kode pos UK, cara teraman untuk melakukannya adalah dengan menggunakan kode pos saat ini. Ada sejumlah opsi:

  • Ordnance Survey merilis Code-Point Open di bawah lisensi data terbuka. Ini akan sangat sedikit ketinggalan zaman tetapi gratis. Ini akan (mungkin - saya tidak ingat) tidak termasuk data Irlandia Utara karena Survei persenjataan tidak memiliki kewenangan di sana. Pemetaan di Irlandia Utara dilakukan oleh Ordnance Survey di Irlandia Utara dan mereka memiliki produk Pointer yang terpisah dan dibayar . Anda dapat menggunakan ini dan menambahkan beberapa yang tidak tercakup dengan cukup mudah.

  • Royal Mail merilis File Alamat Kode Pos (PAF) , ini termasuk BFPO yang saya tidak yakin Code-Point Open tidak. Ini diperbarui secara teratur tetapi membutuhkan biaya (dan mereka kadang-kadang bisa sangat kejam tentangnya). PAF menyertakan alamat lengkap bukan hanya kode pos dan dilengkapi dengan Panduan Programmernya sendiri . Grup Pengguna Data Terbuka (ODUG) saat ini sedang melobi agar PAF dirilis secara gratis, berikut ini adalah deskripsi posisi mereka .

  • Terakhir, ada AddressBase . Ini adalah kolaborasi antara Ordnance Survey, Otoritas Lokal, Royal Mail dan perusahaan yang cocok untuk membuat direktori definitif semua informasi tentang semua alamat UK (mereka sudah cukup sukses juga). Dibayar-untuk tetapi jika Anda bekerja dengan Otoritas Lokal, departemen pemerintah, atau layanan pemerintah gratis untuk digunakan. Ada banyak informasi lebih dari sekadar kode pos yang disertakan.

Ben
sumber
tampilan terdengar menarik
SuperUberDuper
2
sementara ini bukan jawaban yang dicari oleh op, itu mungkin yang paling berguna. Ini akan mendorong saya untuk bersantai dengan aturan pengecekan yang akan saya lakukan.
John Hunt
22

Saya telah melihat beberapa jawaban di atas dan saya akan merekomendasikan untuk tidak menggunakan pola dari jawaban @ Dan (c. 15 Des '10) , karena salah menandai hampir 0,4% dari kode pos yang valid sebagai tidak valid, sementara yang lain tidak .

Ordnance Survey menyediakan layanan yang disebut Code Point Open yang:

berisi daftar semua unit kode pos saat ini di Britania Raya

Saya menjalankan masing-masing regex di atas terhadap daftar lengkap kode pos (6 Juli '13) dari data ini menggunakan grep:

cat CSV/*.csv |
    # Strip leading quotes
    sed -e 's/^"//g' |
    # Strip trailing quote and everything after it
    sed -e 's/".*//g' |
    # Strip any spaces
    sed -E -e 's/ +//g' |
    # Find any lines that do not match the expression
    grep --invert-match --perl-regexp "$pattern"

Ada total 1.686.202 kode pos.

Berikut ini adalah jumlah kode pos yang valid yang tidak cocok dengan masing-masing $pattern:

'^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]?[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$'
# => 6016 (0.36%)
'^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$'
# => 0
'^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$'
# => 0

Tentu saja, hasil ini hanya berurusan dengan kode pos yang valid yang salah ditandai sebagai tidak valid. Begitu:

'^.*$'
# => 0

Saya tidak mengatakan apa pun tentang pola mana yang terbaik untuk memfilter kode pos yang tidak valid.

RichardTowers
sumber
1
Bukankah ini yang saya katakan dalam jawaban saya dan jika Anda pergi ke jalur yang tidak dapat diakses Anda mungkin harus melakukan semuanya, dan tetap memperbarui jika seseorang mengubah jawaban mereka? Jika tidak, setidaknya rujuk tanggal hasil edit terakhir dari jawaban yang Anda ambil sehingga orang dapat melihat apakah sudah diubah sejak saat itu.
Ben
Titik adil. Diedit sesuai. Saya pikir ini menambah diskusi untuk menunjukkan bahwa sebagian besar pola-pola ini tidak mengecualikan salah satu kode CPO, tetapi jawaban yang paling terunggul (valid regex) tidak. Pembaca masa depan: ketahuilah bahwa hasil saya cenderung ketinggalan zaman.
RichardTowers
17
^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$

Ekspresi reguler untuk mencocokkan kode pos UK yang valid. Dalam sistem pos Inggris tidak semua huruf digunakan di semua posisi (sama dengan plat registrasi kendaraan) dan ada berbagai aturan untuk mengatur hal ini. Regex ini memperhitungkan aturan-aturan itu. Detail aturan: Paruh pertama kode pos Format yang valid [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [0-9] [0-9] [AZ] [0-9] [ 0-9] [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [AZ] [0-9] [AZ] [AZ] [0-9] Posisi Pengecualian - Pertama. Contraint - QVX tidak digunakan Posisi - Kedua. Contraint - IJZ tidak digunakan kecuali di Posisi GIR 0AA - Ketiga. Batasan - AEHMNPRTVXY hanya menggunakan Posisi - Keempat. Contraint - ABEHMNPRVWXY Paruh kedua dari kode pos Format yang valid [0-9] [AZ] [AZ] Posisi Pengecualian - Kedua dan Ketiga. Contraint - CIKMOV tidak digunakan

http://regexlib.com/REDetails.aspx?regexp_id=260

Dan
sumber
1
Tidak tahu mengapa orang menurunkan jawaban ini - ini adalah regex yang benar
Ollie
Regex tidak berfungsi untuk kode pos "YO31" dan "YO31 1" dalam Javscript.
Pratik Khadloya
9
Saya tidak berpikir ini benar, karena regex yang diberikan bertentangan dengan deskripsi, dan menyarankan Anda dapat memiliki kode pos dimulai dengan 0-9, yang Anda tidak bisa
Luigi Plinge
4
Regex ini gagal pada sekitar 6000 kode pos yang valid, jadi saya sarankan untuk tidak melakukannya. Lihat jawaban saya .
RichardTowers
ini gagal pada kode pos apa pun dalam huruf kecil atau tanpa ruang untuk saya
Dancer
14

Menurut tabel Wikipedia ini

masukkan deskripsi gambar di sini

Pola ini mencakup semua kasing

(?:[A-Za-z]\d ?\d[A-Za-z]{2})|(?:[A-Za-z][A-Za-z\d]\d ?\d[A-Za-z]{2})|(?:[A-Za-z]{2}\d{2} ?\d[A-Za-z]{2})|(?:[A-Za-z]\d[A-Za-z] ?\d[A-Za-z]{2})|(?:[A-Za-z]{2}\d[A-Za-z] ?\d[A-Za-z]{2})

Saat menggunakannya di Android \ Java use \\ d

AntPachon
sumber
Saya menemukan ini jawaban yang paling mudah dibaca, meskipun hanya mencari bentuk kode pos, bukan kode yang sebenarnya sesuai dengan solusi yang mengambil info dari situs gov.uk, tapi itu cukup baik untuk kasus penggunaan saya. Setelah bermain dengannya sedikit (dalam python), saya memfaktorkannya ke regex yang sedikit lebih kompak tetapi setara yang juga memungkinkan untuk ruang opsional: ([a-zA-Z] (?: (?: [A-zA- Z]? \ D [a-zA-Z]) | (?: \ D {1,2}) | (?: [A-zA-Z] \ d {1,2})) \ W? [0 -9] [a-zA-Z] {2})
Richard J
14

Sebagian besar jawaban di sini tidak berfungsi untuk semua kode pos yang saya miliki di database saya. Saya akhirnya menemukan satu yang sesuai dengan semuanya, menggunakan regex baru yang disediakan oleh pemerintah:

https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/413338/Bulk_Data_Transfer_-_additional_validation_valid_from_March_2015.pdf

Itu tidak ada dalam jawaban sebelumnya, jadi saya mempostingnya di sini kalau-kalau mereka mengambil tautan:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$

UPDATE: Regex Diperbarui seperti yang ditunjukkan oleh Jamie Bull. Tidak yakin apakah itu penyalinan kesalahan saya atau kesalahan dalam regex pemerintah, tautannya turun sekarang ...

UPDATE: Seperti ctwheels ditemukan, regex ini berfungsi dengan rasa javascript regex. Lihat komentarnya untuk salah satu yang bekerja dengan rasa pcre (php).

Jesús Carrera
sumber
1
^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$harus ^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$- tempat perbedaan ;-)
Jamie Bull
1
Temukan! Memperbarui jawaban saya. Terima kasih!
Jesús Carrera
2
Ini adalah satu-satunya jawaban di sini yang berfungsi di regexr.com dan Notepad ++. Meskipun, saya telah mengubahnya ke ([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) ?[0-9][A-Za-z]{2})(dihapus ^dan $dan menambahkan ?spasi setelah) untuk regexr.com untuk menemukan lebih dari satu hasil dan untuk keduanya untuk menemukan hasil yang tidak memiliki pemisah ruang.
mythofechelon
@ctwheels regex ini untuk rasa javascript. Jika tautan gagal Anda, Anda memilih javascript, itu akan berfungsi. Itu tangkapan yang bagus dan saya akan memperbarui jawaban saya.
Jesús Carrera
1
Regex yang diposting dalam dokumentasi secara inheren salah. Seluruh ekspresi harus dibungkus dalam kelompok yang tidak menangkap (?:)dan kemudian jangkar ditempatkan di sekitarnya. Lihat gagal di sini . Untuk informasi lebih lanjut, lihat jawaban saya di sini . ^(?:([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$adalah ekspresi reguler yang diperbaiki.
ctwheels
12

Posting lama tetapi masih cukup tinggi di hasil google jadi saya pikir saya akan memperbarui. Doc 14 Oktober ini mendefinisikan ekspresi reguler kode pos UK sebagai:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([**AZ**a-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$

dari:

https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/359448/4__Bulk_Data_Transfer_-_additional_validation_valid.pdf

Dokumen itu juga menjelaskan logika di baliknya. Namun, ia memiliki kesalahan (tebal) dan juga memungkinkan huruf kecil, yang meskipun legal tidak biasa, jadi versi yang diubah:

^(GIR 0AA)|((([A-Z][0-9]{1,2})|(([A-Z][A-HJ-Y][0-9]{1,2})|(([A-Z][0-9][A-Z])|([A-Z][A-HJ-Y][0-9]?[A-Z])))) [0-9][A-Z]{2})$

Ini berfungsi dengan kode pos London baru (mis. W1D 5LH) yang versi sebelumnya tidak.

deadcrab
sumber
Sepertinya kesalahan yang Anda soroti dengan huruf tebal telah diperbaiki dalam dokumen, tetapi saya masih lebih suka ekspresi reguler Anda karena lebih mudah dibaca.
Profesor pemrograman
5
Satu-satunya hal yang akan saya katakan adalah menjadikan spasi opsional dengan mengubah spasi menjadi \ s? karena ruang bukan persyaratan untuk keterbacaan.
Profesor pemrograman
Regex yang diposting dalam dokumentasi secara inheren salah. Seluruh ekspresi harus dibungkus dalam kelompok yang tidak menangkap (?:)dan kemudian jangkar ditempatkan di sekitarnya. Lihat gagal di sini . Untuk informasi lebih lanjut, lihat jawaban saya di sini . ^(?:([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$adalah ekspresi reguler yang diperbaiki.
ctwheels
10

Ini adalah regex yang dilayani Google di domain i18napis.appspot.com mereka :

GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}
Alix Axel
sumber
10

Kode pos dapat berubah, dan satu-satunya cara yang benar untuk memvalidasi kode pos adalah memiliki daftar kode pos yang lengkap dan melihat apakah ada.

Tetapi ekspresi reguler bermanfaat karena:

  • mudah digunakan dan diimplementasikan
  • pendek
  • cepat dijalankan
  • cukup mudah dirawat (dibandingkan dengan daftar kode pos lengkap)
  • masih menangkap sebagian besar kesalahan input

Tetapi ekspresi reguler cenderung sulit untuk dipertahankan, terutama untuk seseorang yang tidak memunculkannya sejak awal. Jadi itu pasti:

  • semudah mungkin dimengerti
  • bukti yang relatif masa depan

Itu berarti bahwa sebagian besar ekspresi reguler dalam jawaban ini tidak cukup baik. Misalnya saya dapat melihat bahwa [A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]akan mencocokkan area kode pos dari bentuk AA1A - tetapi akan terasa sakit di leher jika dan ketika area kode pos baru ditambahkan, karena sulit untuk memahami area kode pos mana yang cocok.

Saya juga ingin persamaan reguler saya cocok dengan bagian pertama dan kedua dari kode pos sebagai pencocokan tanda kurung.

Jadi saya datang dengan ini:

(GIR(?=\s*0AA)|(?:[BEGLMNSW]|[A-Z]{2})[0-9](?:[0-9]|(?<=N1|E1|SE1|SW1|W1|NW1|EC[0-9]|WC[0-9])[A-HJ-NP-Z])?)\s*([0-9][ABD-HJLNP-UW-Z]{2})

Dalam format PCRE dapat ditulis sebagai berikut:

/^
  ( GIR(?=\s*0AA) # Match the special postcode "GIR 0AA"
    |
    (?:
      [BEGLMNSW] | # There are 8 single-letter postcode areas
      [A-Z]{2}     # All other postcode areas have two letters
      )
    [0-9] # There is always at least one number after the postcode area
    (?:
      [0-9] # And an optional extra number
      |
      # Only certain postcode areas can have an extra letter after the number
      (?<=N1|E1|SE1|SW1|W1|NW1|EC[0-9]|WC[0-9])
      [A-HJ-NP-Z] # Possible letters here may change, but [IO] will never be used
      )?
    )
  \s*
  ([0-9][ABD-HJLNP-UW-Z]{2}) # The last two letters cannot be [CIKMOV]
$/x

Bagi saya ini adalah keseimbangan yang tepat antara memvalidasi sebanyak mungkin, sementara pada saat yang sama pemeriksaan kedepan dan memungkinkan pemeliharaan yang mudah.

andre
sumber
Tidak yakin mengapa Anda ditolak - ini berfungsi dengan semua kode pos yang valid yang telah saya lemparkan dan ruang yang banyak jawaban di atas tidak ditangani dengan benar. Adakah yang mau menjelaskan mengapa?
Jon
1
@ Jon Ini juga cocok ketika karakter lain ditambahkan ke awal atau akhir misalnya aSW1A 1AAasfgcocok untuk saya (saya tidak downvote meskipun sepertinya itu bisa diperbaiki dengan mudah)
decvalts
9

Saya telah mencari regex kode pos Inggris untuk hari terakhir atau lebih dan tersandung pada utas ini. Saya bekerja melalui sebagian besar saran di atas dan tidak ada yang bekerja untuk saya, jadi saya membuat regex sendiri yang, sejauh yang saya tahu, menangkap semua kode pos Inggris yang valid pada Januari '13 (menurut literatur terbaru dari Royal Mail).

Regex dan beberapa kode pos sederhana memeriksa kode PHP diposting di bawah ini. CATATAN: - Hal ini memungkinkan untuk kode pos lebih rendah atau huruf besar dan anomali GIR 0AA tetapi untuk menangani, lebih dari kemungkinan, adanya ruang di tengah kode pos yang dimasukkan itu juga menggunakan str_replace sederhana untuk menghapus ruang sebelum pengujian melawan regex. Perbedaan apa pun di luar itu dan Royal Mail sendiri bahkan tidak menyebutkannya dalam literatur mereka (lihat http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf dan mulai membaca dari halaman 17) !

Catatan: Dalam literatur Royal Mail sendiri (tautan di atas) ada sedikit ambiguitas seputar posisi ke-3 dan ke-4 dan pengecualian di tempat jika karakter ini adalah huruf. Saya menghubungi Royal Mail secara langsung untuk menjernihkannya dan dengan kata-kata mereka sendiri "Sebuah surat di posisi ke-4 Kode Outward dengan format AANA NAA tidak memiliki pengecualian dan pengecualian posisi ke-3 hanya berlaku untuk huruf terakhir dari Kode Outward dengan format ANA NAA. " Langsung dari mulut kuda!

<?php

    $postcoderegex = '/^([g][i][r][0][a][a])$|^((([a-pr-uwyz]{1}([0]|[1-9]\d?))|([a-pr-uwyz]{1}[a-hk-y]{1}([0]|[1-9]\d?))|([a-pr-uwyz]{1}[1-9][a-hjkps-uw]{1})|([a-pr-uwyz]{1}[a-hk-y]{1}[1-9][a-z]{1}))(\d[abd-hjlnp-uw-z]{2})?)$/i';

    $postcode2check = str_replace(' ','',$postcode2check);

    if (preg_match($postcoderegex, $postcode2check)) {

        echo "$postcode2check is a valid postcode<br>";

    } else {

        echo "$postcode2check is not a valid postcode<br>";

    }

?>

Saya harap ini membantu orang lain yang menemukan utas ini mencari solusi.

Dan Solo
sumber
1
Saya ingin tahu contoh kode pos mana yang gagal diterbitkan?
Zhaph - Ben Duguid
Saya tidak bisa memberi Anda kode pos tertentu (tanpa memiliki akses ke daftar PAF lengkap) tetapi kode pos dengan format ANA NAA berpotensi gagal karena huruf P dan Q diperbolehkan di posisi ke-3 dan kode pos dengan format AANA NAA berpotensi juga gagal karena posisi ke-4 memungkinkan semua huruf (regex yang diberikan dalam jawaban yang diterima di atas tidak memperhitungkan salah satu dari ini). Seperti yang saya katakan, saya hanya mengikuti saran saat ini dari Royal Mail - pada saat jawaban di atas, mungkin regex itu sepenuhnya patuh.
Dan Solo
Terima kasih untuk kepala - saya dapat melihat bahwa "P" tampaknya telah ditambahkan sebagai dapat diterima di posisi ketiga (dari dokumen Anda yang ditautkan), tetapi tidak T - tetapi di mana Anda membaca bahwa "posisi ke-4 memungkinkan semua huruf"? Doc tidak menyebutkan "posisi keempat" sama sekali sejauh yang saya bisa lihat, jadi saya akan membacanya sebagai "huruf ketiga terlepas dari posisi aktual".
Zhaph - Ben Duguid
1
Baru saja mendapat kabar dari tim pendukung Royal Mail dan interpretasi saya tentang aturan tampaknya benar. Sebuah huruf di posisi ke-4 Kode Luar (mis. AANA NAA) tidak memiliki pengecualian dan pengecualian posisi ke-3 hanya berlaku untuk huruf terakhir (mis. ANA NAA). Langsung dari mulut kuda.
Dan Solo
1
@DanSolo Regex ini akan mengembalikan kecocokan sejati untuk bagian pertama dari kode pos yang valid kehilangan kode dalam misalnya SW1Aatau BD25tanpa babak kedua (atau setidaknya itu untuk saya)
decvalts
7

Berikut adalah regex berdasarkan format yang ditentukan dalam dokumen yang ditautkan dengan jawaban marcj:

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$/

Satu-satunya perbedaan antara itu dan spesifikasi adalah bahwa 2 karakter terakhir tidak boleh dalam [CIKMOV] sesuai dengan spesifikasi.

Sunting: Ini versi lain yang menguji batasan karakter yang tertinggal.

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
Will Tomlin
sumber
Ada lebih banyak kerumitan pada kode pos UK daripada hanya menerima A-Z- Qtidak pernah diizinkan, Vhanya digunakan dengan hemat, dll. Tergantung pada posisi karakter.
Zhaph - Ben Duguid
2
Itu mungkin tidak relevan jika yang Anda inginkan adalah pemeriksaan sintaks. Seperti yang banyak orang lain katakan, hanya pencarian dalam basis data terbaru yang hampir benar, dan bahkan kemudian ada masalah tentang seberapa mutakhirnya basis data. Jadi, bagi saya, regex checker sintaks ini jelas, sederhana dan bermanfaat.
Rick-777
5

Beberapa regex di atas sedikit membatasi. Catat kode pos asli: "W1K 7AA" akan gagal mengingat aturan "Posisi 3 - AEHMNPRTVXY hanya menggunakan" di atas karena "K" akan dianulir.

regex:

^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKPS-UW])[0-9][ABD-HJLNP-UW-Z]{2})$

Tampaknya sedikit lebih akurat, lihat artikel Wikipedia yang berjudul 'Kode Pos di Inggris' .

Perhatikan bahwa regex ini hanya membutuhkan karakter huruf besar.

Pertanyaan yang lebih besar adalah apakah Anda membatasi input pengguna untuk mengizinkan hanya kode pos yang benar-benar ada atau apakah Anda hanya mencoba untuk menghentikan pengguna memasukkan sampah lengkap ke bidang formulir. Mencocokkan setiap kode pos yang mungkin dengan benar, dan membuktikannya di masa mendatang, adalah teka-teki yang lebih sulit, dan mungkin tidak sepadan kecuali Anda adalah HMRC.

minglis
sumber
Sepertinya kantor pos telah pindah, tetapi pemerintah agak tertinggal :(
Zhaph - Ben Duguid
4
Saya menggunakan ini: "^ ([Gg] [Ii] [Rr] 0 [Aa] {2}) | (([[A-Za-z] [0-9] {1,2}) | (( [A-Za-z] [A-Ha-hJ-Yj-y] [0-9] {1,2}) | (([A-Za-z] [0-9] [A-Za-z ]) | ([A-Za-z] [A-Ha-hJ-Yj-y] [0-9]? [A-Za-z]))))) {0,1} [0-9] [ A-Za-z] {2}) $ "Saya menyukainya karena memungkinkan huruf besar dan kecil dan menjadikan ruang opsional - lebih baik untuk kegunaan, jika tidak 100% benar!
bigtv
4

inilah cara kami menangani masalah kode pos UK:

^([A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[ ]?)([0-9]{1}[A-Za-z]{2})$

Penjelasan:

  • mengharapkan 1 atau 2 az chars, denda atas atau bawah
  • mengharapkan 1 atau 2 angka
  • mengharapkan 0 atau 1 az char, denda atas atau bawah
  • ruang opsional diizinkan
  • mengharapkan 1 angka
  • mengharapkan 2 az, denda atas atau bawah

Ini mendapatkan sebagian besar format, kami kemudian menggunakan db untuk memvalidasi apakah kode pos itu benar-benar nyata, data ini didorong oleh openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html

semoga ini membantu

Alex Stephens
sumber
Ini memungkinkan format AANNA NAA, yang tidak valid.
ctwheels
Karenanya bagian 'Ini mendapat sebagian besar format' dari jawabannya. :)
Alex Stephens
4

Aturan dasar:

^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$

Kode pos di Inggris (atau kode pos, demikian sebutannya) terdiri dari lima hingga tujuh karakter alfanumerik yang dipisahkan oleh spasi. Aturan yang mencakup karakter mana yang dapat muncul pada posisi tertentu agak rumit dan penuh dengan pengecualian. Ekspresi reguler yang baru saja ditampilkan oleh karena itu tetap berpegang pada aturan dasar.

Aturan lengkap:

Jika Anda memerlukan regex yang mencentang semua kotak untuk aturan kode pos dengan mengorbankan keterbacaan, ini dia:

^(?:(?:[A-PR-UWYZ][0-9]{1,2}|[A-PR-UWYZ][A-HK-Y][0-9]{1,2}|[A-PR-UWYZ][0-9][A-HJKSTUW]|[A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]) [0-9][ABD-HJLNP-UW-Z]{2}|GIR 0AA)$

Sumber: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s16.html

Diuji terhadap basis data pelanggan kami dan tampaknya sangat akurat.

Raphos
sumber
4

Saya menggunakan regex berikut yang telah saya uji terhadap semua kode pos Inggris yang valid. Ini didasarkan pada aturan yang direkomendasikan, tetapi diringkas sebanyak yang masuk akal dan tidak menggunakan aturan regex khusus bahasa khusus.

([A-PR-UWYZ]([A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y])?|[0-9]([0-9]|[A-HJKPSTUW])?) ?[0-9][ABD-HJLNP-UW-Z]{2})

Itu mengasumsikan bahwa kode pos telah dikonversi ke huruf besar dan belum mengarah atau mengekor karakter, tetapi akan menerima ruang opsional antara kode keluar dan masuk.

Kode pos "GIR0 0AA" khusus dikecualikan dan tidak akan divalidasi karena tidak ada dalam daftar kode pos resmi Kantor Pos dan sejauh yang saya ketahui tidak akan digunakan sebagai alamat terdaftar. Menambahkannya harus sepele sebagai kasus khusus jika diperlukan.

Pahat
sumber
4

Saya ingin regex sederhana, di mana boleh saja membiarkan terlalu banyak, tetapi tidak menyangkal kode pos yang valid. Aku pergi dengan ini (inputnya adalah string dilucuti / dipangkas):

/^([a-z0-9]\s*){5,8}$/i

Ini memungkinkan kode pos terpendek seperti "L1 8JQ" serta yang terpanjang seperti "OL14 5ET".

Karena memungkinkan hingga 8 karakter, itu juga akan memungkinkan kode pos 8 karakter yang salah jika tidak ada ruang: "OL145ETX". Tetapi sekali lagi, ini adalah regex sederhana, karena saat itu sudah cukup baik.

Henrik N
sumber
Oh, maafkan saya. Saya pikir saya melewatkan / i ketika saya menguji kemarin.
John
3

Paruh pertama dari kode pos Format yang valid

  • [AZ] [AZ] [0-9] [AZ]
  • [AZ] [AZ] [0-9] [0-9]
  • [AZ] [0-9] [0-9]
  • [AZ] [AZ] [0-9]
  • [AZ] [AZ] [AZ]
  • [AZ] [0-9] [AZ]
  • [AZ] [0-9]

Pengecualian
Posisi 1 - QVX tidak digunakan
Posisi 2 - IJZ tidak digunakan kecuali di GIR 0AA
Posisi 3 - AEHMNPRTVXY hanya menggunakan
Posisi 4 - ABEHMNPRVWXY

Bagian kedua dari kode pos

  • [0-9] [AZ] [AZ]

Pengecualian
Posisi 2 + 3 - CIKMOV tidak digunakan

Ingat tidak semua kode yang mungkin digunakan, jadi daftar ini adalah kondisi yang diperlukan tetapi tidak mencukupi untuk kode yang valid. Mungkin lebih mudah untuk hanya mencocokkan dengan daftar semua kode yang valid?

Martin Beckett
sumber
3

Untuk memeriksa kode pos ada dalam format yang valid sesuai panduan pemrogram Royal Mail :

          |----------------------------outward code------------------------------| |------inward code-----|
#special↓       α1        α2    AAN  AANA      AANN      AN    ANN    ANA (α3)        N         AA
^(GIR 0AA|[A-PR-UWYZ]([A-HK-Y]([0-9][A-Z]?|[1-9][0-9])|[1-9]([0-9]|[A-HJKPSTUW])?) [0-9][ABD-HJLNP-UW-Z]{2})$

Semua kode pos pada doogal.co.uk cocok, kecuali yang tidak lagi digunakan.

Menambahkan ?spasi setelahnya dan menggunakan kecocokan dengan huruf besar-kecil untuk menjawab pertanyaan ini:

'se50eg'.match(/^(GIR 0AA|[A-PR-UWYZ]([A-HK-Y]([0-9][A-Z]?|[1-9][0-9])|[1-9]([0-9]|[A-HJKPSTUW])?) ?[0-9][ABD-HJLNP-UW-Z]{2})$/ig);
Array [ "se50eg" ]
Jackson Pauls
sumber
3

Yang ini memungkinkan ruang dan tab kosong dari kedua sisi jika Anda tidak ingin gagal validasi dan kemudian memotongnya.

^\s*(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})\s*$)
Matas Vaitkevicius
sumber
Ini adalah satu-satunya pola yang bekerja untuk saya menggunakan c # (System.Text.RegularExpressions) dengan contoh-contoh yang dijelaskan dalam pertanyaan asli
MattjeS
Ini adalah regex pemerintah Inggris yang rusak dan gagal memvalidasi beberapa format yang valid.
ctwheels
@ctwheels Hai, bisakah Anda memberikan kode pos yang gagal, terima kasih.
Matas Vaitkevicius
Misalnya AAA 1AAbukan format yang valid: lihat jawaban saya untuk penjelasan dan perbaiki.
ctwheels
2

Untuk menambahkan ke daftar ini, regex yang lebih praktis yang saya gunakan yang memungkinkan pengguna untuk memasukkan empty stringadalah:

^$|^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,1}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

Regex ini memungkinkan huruf kapital dan huruf kecil dengan ruang opsional di antaranya

Dari sudut pandang pengembang perangkat lunak regex ini berguna untuk perangkat lunak di mana alamat mungkin opsional. Misalnya, jika pengguna tidak ingin memberikan detail alamatnya

pengguna1
sumber
1

Lihatlah kode python di halaman ini:

http://www.brunningonline.net/simon/blog/archives/001292.html

Saya punya beberapa kode pos yang harus dilakukan. Persyaratannya cukup sederhana; Saya harus mengurai kode pos menjadi kode sandi dan (opsional) memasukkan. Hal baru yang baik adalah bahwa saya tidak harus melakukan validasi apa pun - saya hanya perlu memotong apa yang telah saya berikan dengan cara yang samar-samar cerdas. Saya tidak bisa berasumsi banyak tentang impor saya dalam hal pemformatan, yaitu case dan spasi yang disematkan. Tapi ini bukan berita buruknya; berita buruknya adalah saya harus melakukan semuanya dalam RPG. :-(

Namun demikian, saya melemparkan fungsi Python kecil bersama untuk mengklarifikasi pemikiran saya.

Saya telah menggunakannya untuk memproses kode pos untuk saya.

Rudiger Wolf
sumber
1

Kami diberi spec:

Kode pos UK harus dalam salah satu bentuk berikut (dengan satu pengecualian, lihat di bawah): 
    § A9 9AA 
    § A99 9AA
    § AA9 9AA
    § AA99 9AA
    § A9A 9AA
    § AA9A 9AA
di mana A mewakili karakter alfabet dan 9 mewakili karakter numerik.
Aturan tambahan berlaku untuk karakter alfabet, sebagai berikut:
    § Karakter di posisi 1 mungkin bukan Q, V atau X
    § Karakter di posisi 2 mungkin bukan I, J atau Z
    § Karakter di posisi 3 mungkin bukan I, L, M, N, O, P, Q, R, V, X, Y atau Z
    § Karakter di posisi 4 mungkin bukan C, D, F, G, I, J, K, L, O, Q, S, T, U atau Z
    § Karakter di dua posisi paling kanan mungkin bukan C, I, K, M, O atau V
Satu-satunya pengecualian yang tidak mengikuti aturan umum ini adalah kode pos "GIR 0AA", yang merupakan kode pos khusus yang valid.

Kami datang dengan ini:

/^([A-PR-UWYZ][A-HK-Y0-9](?:[A-HJKS-UW0-9][ABEHMNPRV-Y0-9]?)?\s*[0-9][ABD-HJLNP-UW-Z]{2}|GIR\s*0AA)$/i

Tetapi perhatikan - ini memungkinkan sejumlah ruang di antara kelompok.

paulslater19
sumber
2
paulslater19, sayangnya solusi Anda memungkinkan kode pos A99A 9AA.
1

Saya memiliki regex untuk validasi Kode Pos UK.

Ini berfungsi untuk semua jenis kode pos baik di dalam maupun luar

^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))) || ^((GIR)[ ]?(0AA))$|^(([A-PR-UWYZ][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][A-HJKS-UW0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][ABEHMNPRVWXY0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$

Ini berfungsi untuk semua jenis format.

Contoh:

AB10 --------------------> HANYA POS KODE

A1 1AA ------------------> KOMBINASI (OUTER DAN INNER) POSTCODE

WC2A --------------------> OUTER

Swift-Master
sumber
1

Jawaban yang diterima mencerminkan aturan yang diberikan oleh Royal Mail, meskipun ada kesalahan ketik pada regex. Kesalahan ketik ini tampaknya juga ada di situs gov.uk (seperti pada halaman arsip XML).

Dalam format A9A 9AA aturan memungkinkan karakter P di posisi ketiga, sementara regex tidak mengizinkannya. Regex yang benar adalah:

(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2}) 

Memendekkan ini menghasilkan regex berikut (yang menggunakan sintaksis Perl / Ruby):

(GIR 0AA)|([A-PR-UWYZ](([0-9]([0-9A-HJKPSTUW])?)|([A-HK-Y][0-9]([0-9ABEHMNPRVWXY])?))\s?[0-9][ABD-HJLNP-UW-Z]{2})

Ini juga termasuk ruang opsional antara blok pertama dan kedua.

Stieb
sumber
1

Apa yang saya temukan di hampir semua variasi dan regex dari pdf transfer massal dan apa yang ada di situs wikipedia adalah ini, khusus untuk wikipedia regex, perlu ada ^ setelah yang pertama | (bilah vertikal). Saya menemukan ini dengan menguji AA9A 9AA, karena jika tidak, cek format untuk A9A 9AA akan memvalidasinya. Untuk Contoh memeriksa EC1D 1BB yang seharusnya tidak valid kembali valid karena C1D 1BB adalah format yang valid.

Inilah yang saya hasilkan untuk regex yang baik:

^([G][I][R] 0[A]{2})|^((([A-Z-[QVX]][0-9]{1,2})|([A-Z-[QVX]][A-HK-Y][0-9]{1,2})|([A-Z-[QVX]][0-9][ABCDEFGHJKPSTUW])|([A-Z-[QVX]][A-HK-Y][0-9][ABEHMNPRVWXY])) [0-9][A-Z-[CIKMOV]]{2})$
Andrew Schliewe
sumber
1

Melalui pengujian dan pengamatan empiris, serta mengonfirmasi dengan https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation , ini adalah versi saya dari regex Python yang dengan benar mem-parsing dan memvalidasi kode pos Inggris:

UK_POSTCODE_REGEX = r'(?P<postcode_area>[A-Z]{1,2})(?P<district>(?:[0-9]{1,2})|(?:[0-9][A-Z]))(?P<sector>[0-9])(?P<postcode>[A-Z]{2})'

Regex ini sederhana dan memiliki kelompok penangkap. Ini tidak termasuk semua validasi kode pos UK legal , tetapi hanya memperhitungkan posisi huruf vs angka.

Inilah cara saya menggunakannya dalam kode:

@dataclass
class UKPostcode:
    postcode_area: str
    district: str
    sector: int
    postcode: str

    # https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
    # Original author of this regex: @jontsai
    # NOTE TO FUTURE DEVELOPER:
    # Verified through empirical testing and observation, as well as confirming with the Wiki article
    # If this regex fails to capture all valid UK postcodes, then I apologize, for I am only human.
    UK_POSTCODE_REGEX = r'(?P<postcode_area>[A-Z]{1,2})(?P<district>(?:[0-9]{1,2})|(?:[0-9][A-Z]))(?P<sector>[0-9])(?P<postcode>[A-Z]{2})'

    @classmethod
    def from_postcode(cls, postcode):
        """Parses a string into a UKPostcode

        Returns a UKPostcode or None
        """
        m = re.match(cls.UK_POSTCODE_REGEX, postcode.replace(' ', ''))

        if m:
            uk_postcode = UKPostcode(
                postcode_area=m.group('postcode_area'),
                district=m.group('district'),
                sector=m.group('sector'),
                postcode=m.group('postcode')
            )
        else:
            uk_postcode = None

        return uk_postcode


def parse_uk_postcode(postcode):
    """Wrapper for UKPostcode.from_postcode
    """
    uk_postcode = UKPostcode.from_postcode(postcode)
    return uk_postcode

Berikut ini adalah unit test:

@pytest.mark.parametrize(
    'postcode, expected', [
        # https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
        (
            'EC1A1BB',
            UKPostcode(
                postcode_area='EC',
                district='1A',
                sector='1',
                postcode='BB'
            ),
        ),
        (
            'W1A0AX',
            UKPostcode(
                postcode_area='W',
                district='1A',
                sector='0',
                postcode='AX'
            ),
        ),
        (
            'M11AE',
            UKPostcode(
                postcode_area='M',
                district='1',
                sector='1',
                postcode='AE'
            ),
        ),
        (
            'B338TH',
            UKPostcode(
                postcode_area='B',
                district='33',
                sector='8',
                postcode='TH'
            )
        ),
        (
            'CR26XH',
            UKPostcode(
                postcode_area='CR',
                district='2',
                sector='6',
                postcode='XH'
            )
        ),
        (
            'DN551PT',
            UKPostcode(
                postcode_area='DN',
                district='55',
                sector='1',
                postcode='PT'
            )
        )
    ]
)
def test_parse_uk_postcode(postcode, expected):
    uk_postcode = parse_uk_postcode(postcode)
    assert(uk_postcode == expected)
jontsai
sumber
0

Saya membutuhkan versi yang akan bekerja di SAS dengan PRXMATCHdan fungsi terkait, jadi saya datang dengan ini:

^[A-PR-UWYZ](([A-HK-Y]?\d\d?)|(\d[A-HJKPSTUW])|([A-HK-Y]\d[ABEHMNPRV-Y]))\s?\d[ABD-HJLNP-UW-Z]{2}$

Menguji kasus dan catatan:

/* 
Notes
The letters QVX are not used in the 1st position.
The letters IJZ are not used in the second position.
The only letters to appear in the third position are ABCDEFGHJKPSTUW when the structure starts with A9A.
The only letters to appear in the fourth position are ABEHMNPRVWXY when the structure starts with AA9A.
The final two letters do not use the letters CIKMOV, so as not to resemble digits or each other when hand-written.
*/

/*
    Bits and pieces
    1st position (any):         [A-PR-UWYZ]         
    2nd position (if letter):   [A-HK-Y]
    3rd position (A1A format):  [A-HJKPSTUW]
    4th position (AA1A format): [ABEHMNPRV-Y]
    Last 2 positions:           [ABD-HJLNP-UW-Z]    
*/


data example;
infile cards truncover;
input valid 1. postcode &$10. Notes &$100.;
flag = prxmatch('/^[A-PR-UWYZ](([A-HK-Y]?\d\d?)|(\d[A-HJKPSTUW])|([A-HK-Y]\d[ABEHMNPRV-Y]))\s?\d[ABD-HJLNP-UW-Z]{2}$/',strip(postcode));
cards;
1  EC1A 1BB  Special case 1
1  W1A 0AX   Special case 2
1  M1 1AE    Standard format
1  B33 8TH   Standard format
1  CR2 6XH   Standard format
1  DN55 1PT  Standard format
0  QN55 1PT  Bad letter in 1st position
0  DI55 1PT  Bad letter in 2nd position
0  W1Z 0AX   Bad letter in 3rd position
0  EC1Z 1BB  Bad letter in 4th position
0  DN55 1CT  Bad letter in 2nd group
0  A11A 1AA  Invalid digits in 1st group
0  AA11A 1AA  1st group too long
0  AA11 1AAA  2nd group too long
0  AA11 1AAA  2nd group too long
0  AAA 1AA   No digit in 1st group
0  AA 1AA    No digit in 1st group
0  A 1AA     No digit in 1st group
0  1A 1AA    Missing letter in 1st group
0  1 1AA     Missing letter in 1st group
0  11 1AA    Missing letter in 1st group
0  AA1 1A    Missing letter in 2nd group
0  AA1 1     Missing letter in 2nd group
;
run;
pengguna667489
sumber
0

Metode di bawah ini akan memeriksa kode pos dan memberikan info lengkap

const valid_postcode = postcode => {
    try {
        postcode = postcode.replace(/\s/g, "");
        const fromat = postcode
            .toUpperCase()
            .match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/);
        const finalValue = `${fromat[1]} ${fromat[2]}`;
        const regex = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$/i;
        return {
            isValid: regex.test(postcode),
            formatedPostCode: finalValue,
            error: false,
            info: 'It is a valid postcode'
        };
    } catch (error) {
        return { error: true , info: 'Invalid post code has been entered!'};
    }
};
valid_postcode('GU348RR')
result => {isValid: true, formatedPostCode: "GU34 8RR", error: false, info: "It is a valid postcode"}
valid_postcode('sdasd4746asd')
result => {error: true, info: "Invalid post code has been entered!"}
valid_postcode('787898523')
result => {error: true, info: "Invalid post code has been entered!"}
Aathi
sumber