Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
UK postcode parsing and validation for Ruby for writing friendly software.
Features:
I
/1
and O
/0
.wiaiaa
to W1A 1AA
).W1A
)Note: There's a distinction between validity and existence. This library validates the format of a postcode, but not whether it actually currently refers to a location.
By analogy, name@somedomainthatdoesnotexist.com
is a valid email address in
terms of format, but you can't successfully deliver an email to it.
require "uk_postcode"
Parse and extract sections of a full postcode:
pc = UKPostcode.parse("W1A 2AB")
pc.valid? # => true
pc.full? # => true
pc.full_valid? # => true
pc.outcode # => "W1A"
pc.incode # => "2AB"
pc.area # => "W"
pc.district # => "1A"
pc.sector # => "2"
pc.unit # => "AB"
Or of a partial postcode:
pc = UKPostcode.parse("W1A")
pc.valid? # => true
pc.full? # => false
pc.full_valid? # => false
pc.outcode # => "W1A"
pc.incode # => nil
pc.area # => "W"
pc.district # => "1A"
pc.sector # => nil
pc.unit # => nil
Postcodes are converted to a normal or canonical form:
pc = UKPostcode.parse("w1a1aa")
pc.valid? # => true
pc.area # => "W"
pc.district # => "1A"
pc.sector # => "1"
pc.unit # => "AA
pc.to_s # => "W1A 1AA"
And mistakes with I/1 and O/0 are corrected:
pc = UKPostcode.parse("WIA OAA")
pc.valid? # => true
pc.area # => "W"
pc.district # => "1A"
pc.sector # => "0"
pc.unit # => "AA
pc.to_s # => "W1A 0AA"
Find the country of a full or partial postcode (if possible: some outcodes span countries):
UKPostcode.parse("W1A 1AA").country # => :england
UKPostcode.parse("BT4").country # => :northern_ireland
UKPostcode.parse("CA6").country # => :unknown
UKPostcode.parse("CA6 5HS").country # => :scotland
UKPostcode.parse("CA6 5HT").country # => :england
The country returned for a postcode is derived from the ONS Postcode Directory and might not always be correct in a border region:
Users should note that postcodes that straddle two geographic areas will be assigned to the area where the mean grid reference of all the addresses within the postcode falls.
Invalid postcodes:
pc = UKPostcode.parse("Not Valid")
pc.valid? # => false
pc.full? # => false
pc.full_valid? # => false
pc.area # => nil
pc.to_s # => "Not valid"
pc.country # => :unknown
You can normalise postcodes on assignment by overriding a setter method (this
assumes that you have a postcode
field on the model):
def postcode=(str)
super UKPostcode.parse(str).to_s
end
Invalid postcodes are parsed to instances of InvalidPostcode
, whose #to_s
method gives the original input, so an invalid postcode will be presented back
to the user as originally entered.
To validate, use something like this:
class PostcodeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
ukpc = UKPostcode.parse(value)
unless ukpc.full_valid?
record.errors[attribute] << "not recognised as a UK postcode"
end
end
end
class Address
validates :postcode, presence: true, postcode: true
end
The interface has changed significantly, so code that worked with version 1.x will not work with version 2.x without changes.
Specifically:
UKPostcode.parse(str)
where you previously used UKPostcode.new(str)
.parse
will return either a GeographicPostcode
, a GiroPostcode
, or an
InvalidPostcode
.GeographicPostcode.parse
directly if you wish to
exclude GIR 0AA
and invalid postcodes.In your Gemfile
:
gem "uk_postcode", "~> 2.1.0"
To run the test suite:
$ rake
The full list of UK postcodes is not included in the repository due to its size, but will be fetched automatically from mySociety.
If you are running an automatic build process, please find a way to cache these files between runs.
No. The old postcode was SAN TA1; the current one is XM4 5HQ. (XMAS HQ, geddit?) For most people, these probably aren't useful, as they don't correspond to actual locations, and are only used by Royal Mail internally.
See "Adding additional formats" if you'd like to support this.
No. They're not really postcodes, though they serve a similar purpose. Some of them are abroad; some of them are on boats that move around; some of them are ephemeral and exist only for particular operations. This library has been designed with the assumption that most people won't want to handle BFPO codes, and that those that do can do so explicitly.
See "Adding additional formats" if you'd like to support them.
The new BF1 format postcodes can be parsed, although their location is always unknown.
Parsing is implemented via the ParserChain
class, which attempts to parse
the supplied text via each parser in turn.
The UKPostcode.parse
method is effectively a thin wrapper that does this:
chain = ParserChain.new(GiroPostcode, GeographicPostcode, InvalidPostcode)
chain.parse(str)
Each class passed to ParserChain.new
must implement a class method
parse(str)
and return either a postcode object (see AbstractPostcode
) or
nil.
The first non-nil object is returned.
InvalidPostcode
is at the end of the chain to ensure that a postcode object
is always returned.
To add an additional class, subclass AbstractPostcode
, implement the abstract
methods, and instantiate your own ParserChain
.
You may use this library according to the terms of the MIT License; see COPYING.txt for details.
The regular expressions in country_lookup.rb
are derived from the ONS
Postcode Directory according to the terms of the
Open Government Licence.
Under the terms of the Open Government Licence (OGL) […] anyone wishing to use or re-use ONS material, whether commercially or privately, may do so freely without a specific application for a licence, subject to the conditions of the OGL and the Framework. Users reproducing ONS content must include a source accreditation to ONS.
In order to avoid the restrictive commercial terms of the Northern Ireland
data in the ONSPD, this is not used to generate the regular expressions.
Fortunately, Northern Ireland postcodes are very simple: they all start with
BT
!
FAQs
Unknown package
We found that uk_postcode demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.