Skip to content

Instantly share code, notes, and snippets.

@daliborgogic
Last active October 14, 2022 16:58
Show Gist options
  • Select an option

  • Save daliborgogic/7cce7023e7d1f3d9ff0f8a630e765aab to your computer and use it in GitHub Desktop.

Select an option

Save daliborgogic/7cce7023e7d1f3d9ff0f8a630e765aab to your computer and use it in GitHub Desktop.

Revisions

  1. daliborgogic revised this gist Oct 14, 2022. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    {
    "scripts": {
    "test": "vitest"
    },
    "devDependencies": {
    "vitest": "^0.24.3"
    }
    }
  2. daliborgogic revised this gist Oct 14, 2022. No changes.
  3. daliborgogic revised this gist Oct 14, 2022. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions postcodes.test.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    import { expect, test } from 'vitest'

    import { isGBPostcode, isPostcode } from '../src/uses/usePostcode.js'

    test('is GB', () => {
    expect(isGBPostcode('SW1W 0NY')).toBe(true)
    expect(isGBPostcode('PO16 7GZ')).toBe(true)
    expect(isGBPostcode('GU16 7HF')).toBe(true)
    expect(isGBPostcode('L1 8JQ')).toBe(true)
    expect(isGBPostcode('L1 8JQ$')).toBe(false)
    })

    test('is DE', () => {
    expect(isPostcode('DE', '84419')).toBe(true)
    })

    test('is AT', () => {
    expect(isPostcode('AT', '1010')).toBe(true)
    expect(isPostcode('AT', '1423')).toBe(true)
    expect(isPostcode('AT', '5020')).toBe(true)
    })

    test('is Ireland', () => {
    expect(isPostcode('IE', 'A65 F4E2')).toBe(true)
    expect(isPostcode('IE', 'D02 AF30')).toBe(true)
    })
  4. daliborgogic revised this gist Oct 14, 2022. 1 changed file with 0 additions and 4 deletions.
    4 changes: 0 additions & 4 deletions usePostcode.js
    Original file line number Diff line number Diff line change
    @@ -36,11 +36,7 @@ export const isGBPostcode = postcode => {
    let valid = false

    // Check the string against the six types of postcodes.
    console.log('postcode ', postcode)
    console.log('pcexp ', pcexp)
    for (const el of pcexp) {
    console.log('el ', el)
    console.log('match ', postcode.match(el))
    if (postcode.match(el)) {
    valid = true
    break
  5. daliborgogic created this gist Oct 14, 2022.
    130 changes: 130 additions & 0 deletions usePostcode.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    const normalizePostcode = postcode => postcode.toUpperCase().trim().replace(/\s/g, '')

    export const isGBPostcode = postcode => {
    // Permitted letters depend upon their position in the postcode.
    // https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation.
    const ALPHA1 = '[abcdefghijklmnoprstuwyz]' // Character 1.
    const ALPHA2 = '[abcdefghklmnopqrstuvwxy]' // Character 2.
    const ALPHA3 = '[abcdefghjkpstuw]' // Character 3 == ABCDEFGHJKPSTUW.
    const ALPHA4 = '[abehmnprvwxy]' // Character 4 == ABEHMNPRVWXY.
    const ALPHA5 = '[abdefghjlnpqrstuwxyz]' // Character 5 != CIKMOV.

    const pcexp = []

    // Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA.
    pcexp[0] = `^(${ALPHA1}{1}${ALPHA2}{0,1}[0-9]{1,2})([0-9]{1}${ALPHA5}{2})$`

    // Expression for postcodes: ANA NAA.
    pcexp[1] = `^(${ALPHA1}{1}[0-9]{1}${ALPHA3}{1})([0-9]{1}${ALPHA5}{2})$`

    // Expression for postcodes: AANA NAA.
    pcexp[2] = `^(${ALPHA1}{1}${ALPHA2}[0-9]{1}${ALPHA4})([0-9]{1}${ALPHA5}{2})$`

    // Exception for the special postcode GIR 0AA.
    pcexp[3] = '^(gir)(0aa)$'

    // Standard BFPO numbers.
    pcexp[4] = '/^(bfpo)([0-9]{1,4})$/'

    // c/o BFPO numbers.
    pcexp[5] = '/^(bfpo)(c/o[0-9]{1,3})$/'

    // Load up the string to check, converting into lowercase and removing spaces.
    postcode = postcode.toLowerCase().replace(/\s/g, '')

    // Assume we are not going to find a valid postcode.
    let valid = false

    // Check the string against the six types of postcodes.
    console.log('postcode ', postcode)
    console.log('pcexp ', pcexp)
    for (const el of pcexp) {
    console.log('el ', el)
    console.log('match ', postcode.match(el))
    if (postcode.match(el)) {
    valid = true
    break
    }
    }

    return valid
    }

    export const isPostcode = (country, postcode) => {
    // Assume we are not going to find a valid postcode.
    let valid = true
    if (postcode.replace(/^[\s\-A-Za-z0-9]+$/, '').trim().length > 0) {
    return false;
    }
    switch (country) {
    case 'AT':
    valid = /^([0-9]{4})$/.test(postcode)
    break
    case 'BA':
    valid = /^([7-8]{1})([0-9]{4})$/.test(postcode)
    break
    case 'BE':
    valid = /^([0-9]{4})$/i.test(postcode)
    break
    case 'BR':
    valid = /^([0-9]{5})([-])?([0-9]{3})$/.test(postcode)
    break
    case 'CH':
    valid = /^([0-9]{4})$/i.test(postcode)
    break
    case 'DE':
    valid = /^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/.test(postcode)
    break
    case 'ES':
    case 'FR':
    case 'IT':
    valid = /^([0-9]{5})$/i.test(postcode)
    break
    case 'GB':
    valid = isGBPostcode(postcode)
    break
    case 'HU':
    valid = /^([0-9]{4})$/i.test(postcode)
    break
    case 'IE':
    valid = /([AC-FHKNPRTV-Y]\d{2}|D6W)[0-9AC-FHKNPRTV-Y]{4}/.test(normalizePostcode(postcode))
    break
    case 'IN':
    valid = /^[1-9]{1}[0-9]{2}\s{0,1}[0-9]{3}$/.test(postcode)
    break
    case 'JP':
    valid = /^([0-9]{3})([-]?)([0-9]{4})$/.test(postcode)
    break
    case 'PT':
    valid = /^([0-9]{4})([-])([0-9]{3})$/.test(postcode)
    break
    case 'PR':
    case 'US':
    valid = /^([0-9]{5})(-[0-9]{4})?$/i.test(postcode)
    break
    case 'CA':
    // CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes.
    valid = /^([ABCEGHJKLMNPRSTVXY]d[ABCEGHJKLMNPRSTVWXYZ])([ ])?(d[ABCEGHJKLMNPRSTVWXYZ]d)$/i.test(postcode)
    break
    case 'PL':
    valid = /^([0-9]{2})([-])([0-9]{3})$/.test(postcode)
    break
    case 'CZ':
    case 'SK':
    valid = /^([0-9]{3})(s?)([0-9]{2})$/.test(postcode)
    break
    case 'NL':
    valid = /^([1-9][0-9]{3})(s?)(?!SA|SD|SS)[A-Z]{2}$/i.test(postcode)
    break
    case 'SI':
    valid = /^([1-9][0-9]{3})$/.test(postcode)
    break
    case 'LI':
    valid = /^(94[8-9][0-9])$/.test(postcode)
    break
    default:
    valid = true
    break
    }
    return valid
    }