Reputation: 693
I'm trying to find a way to split a UK postcode from the user entry. The initial entry is validated by the below regex and it's working fine.
var 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})$";
Now I need to split the postcode into outward and inward codes so that I can send them separately to the client's ERP to get the shipping cost.
Example.
User input: DD81UN
Desired output: DD8 1UNUser input: DN551PT
Desired output: DN55 1PT
Upvotes: 3
Views: 2004
Reputation: 4981
Only adding spaces:
As per the wikipedia entry on outward and inward codes for UK Postal codes, the rules are as follows:
So if you have already extracted the code, to add spaces or split, simply add a space before the 3rd character from the end since the inward code is always 3 characters in length:
string extractedCode = "DD81UN";
extractedCode = extractedCode.Insert(extractedCode.Length - 3, " ");
// Output: DD8 1UN
Improving the Regular expression:
Based on the rules in the link you shared, here's a better version of the regex, that extracts UK Postal Codes from any text, even if they contain a space:
\b([A-PR-UWYZ](?:(?:\d{1,2}|\d[A-HJ-KSTUW])|(?:[A-HK-Y]\d(?:\d|[A-Z])?)))\s?(\d[ABD-HJLNP-UW-Z]{2})\b
\b
represents word boundary at start and end([A-PR-UWYZ](?:(?:\d{1,2}|\d[A-HJ-KSTUW])|(?:[A-HK-Y]\d(?:\d|[A-Z])?)))
is the first capturing group to match outward code which may be two to four characters in length.
[A-PR-UWYZ]
since the first character cannot have Q
, V
or X
(?:\d{1,2}|\d[A-HJ-KSTUW])
allows formats AN
, ANN
and ANA
and restricts characters as per the rules in the third position(?:[A-HK-Y]\d(?:\d|[A-Z])?))
allows formats AAN
, AANN
and AANA
and doesn't allow I
, J
and Z
in the 2nd position\s?
matches an optional space between outward and inward codes.(\d[ABD-HJLNP-UW-Z]{2})
is the second capturing group for outward codes. It allows one digit followed by two characters as per the rules.If your objective is to only match and add space, match using above and replace with $1 $2
since the above regex matches outward codes in the first group and inward codes in the 2nd group.
Here's a dotnet fiddle which demonstrates the same.
string input = "sample DD81UN DN55 1PT WRONG text 123456";
Regex r = new Regex(@"\b([A-PR-UWYZ](?:(?:\d{1,2}|\d[A-HJ-KSTUW])|(?:[A-HK-Y]\d(?:\d|[A-Z])?)))\s?(\d[ABD-HJLNP-UW-Z]{2})\b");
// To add spaces between each codes
string output = r.Replace(input, "$1 $2");
// To get all codes
var results = r.Matches(output);
Upvotes: 3
Reputation: 4638
Try This.
namespace UKPostCodeConsoleApp
{
class Program
{
static void Main(string[] args)
{
string firstPostCode = "DD81UN";
string secondPostCode = "DN551PT";
Console.WriteLine(ParseToUkPostcode(firstPostCode));
Console.WriteLine(ParseToUkPostcode(secondPostCode));
Console.Read();
}
public static string ParseToUkPostcode(string aPostcode)
{
string finalPostcode = aPostcode;
finalPostcode = finalPostcode.Replace(" ", "").Trim();
string outWardResult = finalPostcode.Substring(0, finalPostcode.Length - 3);
string inWardResult = finalPostcode.Substring(Math.Max(0, finalPostcode.Length - 3));
string postCodeResult = string.Format("{0} {1}", outWardResult, inWardResult);
finalPostcode = postCodeResult;
return finalPostcode;
}
}
}
OUTPUT
Hope it solves your problem
Upvotes: 1