Friday, March 17, 2006

UK Postcode Implementation

I've been meaning to put this up here ever since the day after my post about regular expressions but time has eluded me until now. I had a stab at coming up with some code for a postcode to save doing the same old checking (or alternatively none at all!) every time; let me know what you think.
namespace Diuturnal.Utility {
[Serializable]
public struct Postcode {
private const string ValidationString =
@"^\s*(?<out>[A-Z]{1,2}[0-9R][0-9A-Z]?) *(?<in>[0-9][A-Z-[CIKMOV]]{2})\s*$";
private static readonly Regex _validator =
new Regex(ValidationString);
public static readonly Postcode Empty =
new Postcode(string.Empty, string.Empty);
private string _outCode;
private string _inCode;
private Postcode(string outCode, string inCode) {
_outCode = outCode;
_inCode = inCode;
}
public override string ToString() {
if (0 == _outCode.Length) {
return string.Empty;
}
return _outCode + " " + _inCode;
}
public override bool Equals(object obj) {
if (!(obj is Postcode)) {
return false;
}
return (this == (Postcode) obj);
}
public override int GetHashCode() {
return this.ToString().GetHashCode();
}
public static bool operator ==(Postcode lhs, Postcode rhs) {
return (lhs.ToString() == rhs.ToString());
}
public static bool operator !=(Postcode lhs, Postcode rhs) {
return !(lhs == rhs);
}
public static Postcode Parse(string s) {
if (null == s) {
throw new ArgumentNullException();
}
string capitalised = s.ToUpper();
if (!_validator.IsMatch(capitalised)) {
throw new FormatException();
}
return new Postcode(_validator.Replace(capitalised, "${out}"),
_validator.Replace(capitalised, "${in}"));
}
public static bool TryParse(string s, out Postcode result) {
if (null == s) {
result = Postcode.Empty;
return false;
}
string capitalised = s.ToUpper();
if (!_validator.IsMatch(capitalised)) {
result = Postcode.Empty;
return false;
}
result = new Postcode(_validator.Replace(capitalised, "${out}"),
_validator.Replace(capitalised, "${in}"));
return true;
}
}
}
view raw Postcode.cs hosted with ❤ by GitHub