Код: Выделить всё
'''
using System;
namespace CorrectAddress
{
class AddressCorrector
{
// make an array of abbreviations and references full forms for provinces
static readonly (string ProvinceAbbreviation, string Province)[] Provinces = new[]
{
("AB","ALBERTA"),
("BC","BRITISH COLUMBIA"),
("MB","MANITOBA"),
("NB","NEW BRUNSWICK"),
("NL","NEWFOUNDLAND AND LABRADOR"),
("NS","NOVA SCOTIA"),
("ON","ONTARIO"),
("PE","PRINCE EDWARD ISLAND"),
("QC","QUEBEC"),
("SK","SASKATCHEWAN"),
("NT","NORTHWEST TERRITORIES"),
("NU","NUNAVUT"),
("YT","YUKON")
};
//makes an array of full streets
static readonly string[] FullForms = new[]
{
"STREET", // 0
"ROAD", // 1
"BOULEVARD", // 2
"DRIVE", // 3
"LANE", // 4
"PARKWAY", // 5
"COURT", // 6
"CIRCLE", // 7
"TERRACE", // 8
"PLACE", // 9
"SQUARE", // 10
"TRAIL", // 11
"CRESCENT", // 12
"HIGHWAY", // 13
"EXPRESSWAY", // 14
"ALLEY", // 15
"GARDENS", // 16
"CROSSING", // 17
"VIEW", // 18
"POINT", // 19
"MOUNT", // 20
"FORK", // 21
"HEIGHTS", // 22
"GLEN", // 23
"HOLLOW", // 24
"KNOLL", // 25
"MEADOW", // 26
"PLAINS", // 27
"RIDGE", // 28
"RIVER", // 29
"SHORES", // 30
"SPRINGS", // 31
"SUMMIT", // 32
"VALLEY", // 33
"VILLAGE", // 34
"VISTA", // 35
"AVENUE" //36
};
// make an array of abbreviations and references full forms
static readonly (string StreetAbbreviation, int FullFormIndex)[] StreetDescriptorMapping = new[]
{
("AVE",36),
("ST", 0),
("RD", 1),
("BLVD", 2),
("DR", 3),
("LN", 4),
("PKY", 5),
("PKWY", 5),
("CT", 6),
("CRT", 6),
("CTR", 6),
("CIR", 7),
("TER", 8),
("PL", 9),
("SQ", 10),
("TRL", 11),
("CRES", 12),
("HWY", 13),
("EXP", 14),
("EXPWY", 14),
("EXPW", 14),
("ALY", 15),
("GDNS", 16),
("XING", 17),
("VW", 18),
("PT", 19),
("MT", 20),
("MNT", 20),
("FRK", 21),
("HTS", 22),
("GLN", 23),
("HOL", 24),
("HOLW", 24),
("KNL", 25),
("MDW", 26),
("PLNS", 27),
("RDG", 28),
("RIV", 29),
("SHR", 30),
("SPGS", 31),
("SMT", 32),
("VLY", 33),
("VLG", 34),
("VIS", 35)
};
static readonly string[] UnitDescriptors = new[]
{
("BASEMENT"),
("LOWER"),
("UPPER"),
("MAIN"),
("TOP FLOOR"),
("PENTHOUSE"),
("GROUND FLOOR"),
("MEZZANINE"),
("ATTIC"),
};
static readonly string[] UnitReplacements = new[]
{
("UNIT"),
("APARTMENT"),
("UPPER"),
("APT"),
("SUITE"),
("LEVEL"),
("RURAL ROUTE"),
("MEZZANINE"),
("ATTIC"),
};
//corrects and changes dhort form to full form ST->STREET once one replacement is found it returns it
static string CorrectStreetDescriptor(string Address)
{
//loops througgh list of abbreviations
foreach (var (StreetAbbreviation, fullFormIndex) in StreetDescriptorMapping)
{
//for each abbreviation it does case true
switch (true)
{
//eg. Ave takes " Ave," and replaces with " AVENUE,"
case bool _ when Address.Contains(" " + StreetAbbreviation + ",", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + ",", " " + FullForms[fullFormIndex] + ",");
return Address;
}
//eg. Ave takes " Ave " and replaces with " AVENUE "
case bool _ when Address.Contains(" " + StreetAbbreviation + " ", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + " ", " " + FullForms[fullFormIndex] + " ");
return Address; ;
}
//eg. Ave takes " Ave." and replaces with " AVENUE"
case bool _ when Address.Contains(" " + StreetAbbreviation + ".", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + ".", " " + FullForms[fullFormIndex]);
return Address;
}
}
}
return Address;
}
static bool IsStreet(string StreetCheck)
{
foreach (var streetType in FullForms)
{
if (StreetCheck.Contains(streetType, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
static string CorrectProvince(string ProvinceForCorrection)
{
//loops througgh list of abbreviations
foreach (var (ProvinceAbbreviation, Province) in Provinces)
{
//for each abbreviation it does case true
if (ProvinceForCorrection.ToUpper() == Province.ToUpper())
{
return ProvinceAbbreviation;
}
}
return ProvinceForCorrection;
}
static string ReplaceUnits(string UnittoCorrect)
{
foreach (var Replacement in UnitReplacements)
{
if (UnittoCorrect.Contains(Replacement,StringComparison.OrdinalIgnoreCase))
{
UnittoCorrect = UnittoCorrect.Replace(Replacement, "", StringComparison.OrdinalIgnoreCase).Trim();
break;
}
}
return UnittoCorrect;
}
static (string Street,string Unit) SplitUnitandStreet(string StreettoCorrect,string UnittoCorrect)
{
foreach (var Descriptor in UnitDescriptors)
{
if (StreettoCorrect.EndsWith(Descriptor, StringComparison.OrdinalIgnoreCase))
{
// Remove the descriptor from the end of the street string
StreettoCorrect = StreettoCorrect.Substring(0, StreettoCorrect.Length - Descriptor.Length).Trim();
if (string.IsNullOrWhiteSpace(UnittoCorrect))
{
UnittoCorrect = Descriptor;
}
else
{
UnittoCorrect = UnittoCorrect + " " + Descriptor;
}
break;
}
}
if (UnittoCorrect == "")
{
string[] StreetSplit = StreettoCorrect.Split(" ");
int UpperBound = StreetSplit.Length - 1;
if (StreetSplit[UpperBound].All(char.IsDigit))
{
if (!(StreetSplit[UpperBound - 1] == "HIGHWAY") && !(StreetSplit[UpperBound - 2] + " " + StreetSplit[UpperBound - 1] == "COUNTY ROAD"))
{
UnittoCorrect = StreetSplit[UpperBound];
StreettoCorrect = ReplaceUnits(string.Join(" ", StreetSplit.Take(UpperBound)));
}
}
else
{
if (StreetSplit[0].Any(char.IsLetter) && !StreetSplit[0].All(char.IsLetter))
{
string StreetNumber = "";
foreach (char c in StreetSplit[0])
{
if (char.IsDigit(c))
{
StreetNumber = StreetNumber + c;
}
else
{
UnittoCorrect = UnittoCorrect + c;
}
}
StreetSplit[0] = StreetNumber;
StreettoCorrect = string.Join(" ", StreetSplit.Take(StreettoCorrect.Length));
}
}
}
else
{
UnittoCorrect = ReplaceUnits(UnittoCorrect);
}
return (StreettoCorrect,UnittoCorrect);
}
static string split_address(string Address)
{
//replace all double commas and number signs
Address = Address.Replace("#", "");
Address = Address.Replace(",,", "");
Address = Address.Replace(", ,", "");
//convert address to uppercase
Address = Address.ToUpper();
//return the correct street descriptor
Address = CorrectStreetDescriptor(Address);
string Street = "";
string Unit = "";
string City = "";
string Province = "";
string PostalCode = "";
string[] textSplitter = Address.Split(',', StringSplitOptions.None);
int upperBound = textSplitter.Length - 1;
//if proper address
if (upperBound >= 2)
{
textSplitter[upperBound] = textSplitter[upperBound].Replace("-", "").Trim();
string temporaryPostalCode = textSplitter[upperBound].Replace(" ", "");
if (temporaryPostalCode.Length == 6)
{
PostalCode = temporaryPostalCode;
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;
Province = CorrectProvince(textSplitter[upperBound].Trim());
}
else
{
PostalCode = temporaryPostalCode.Substring(temporaryPostalCode.Length - 6);
// Get the first 3 characters (e.g. "N3L")
string fsa = PostalCode.Substring(0, 3);
int index = temporaryPostalCode.IndexOf(fsa, StringComparison.OrdinalIgnoreCase);
Province = CorrectProvince(temporaryPostalCode.Substring(0, index).Trim());
}
//resize array to erase ubound
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;
//get city and resize array
City = textSplitter[upperBound].Trim();
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;
//start to get street and unit
if (upperBound == 1) //2 variables street and unit
{
if (IsStreet(textSplitter[upperBound]))
{
Street = textSplitter[upperBound].Trim().ToUpper();
Array.Resize(ref textSplitter, upperBound);
upperBound = textSplitter.Length - 1;
Unit = textSplitter[upperBound].Trim().ToUpper();
}
else
{
Unit = textSplitter[upperBound].Trim().ToUpper();
Array.Resize(ref textSplitter, upperBound);
upperBound = textSplitter.Length - 1;
Street = textSplitter[upperBound].Trim().ToUpper();
}
}
else //1 street+unit or street
{
if (textSplitter[upperBound].Contains("-"))
{
string[] secondarySplitter = textSplitter[upperBound].Split('-', StringSplitOptions.None);
Street = secondarySplitter[1].Trim().ToUpper();
Unit = secondarySplitter[0].Trim().ToUpper();
}
else
{
Street = textSplitter[upperBound].Trim().ToUpper();
}
}
//checks a bit of logic for if unit is the street number
if (!Street.Any(char.IsDigit) && Unit.All(char.IsDigit))
{
if (Street.Contains("Rural Route", StringComparison.OrdinalIgnoreCase) ||
Street == "RR" ||
Street.Contains("POBOX", StringComparison.OrdinalIgnoreCase) ||
Street.Contains("BOX", StringComparison.OrdinalIgnoreCase) ||
Street.Contains("PO BOX", StringComparison.OrdinalIgnoreCase))
{
Street = $"{Street} {Unit}";
Unit = "";
}
else
{
Street = $"{Unit} {Street}";
Unit = "";
}
}
//checks if unti and street are flipped
else if (!Street.Any(char.IsDigit) && !Unit.All(char.IsDigit) && Unit.Any(char.IsDigit))
{
string tempUnit = Street;
string tempStreet = Unit;
Street = tempStreet;
Unit = tempUnit;
}
(Street, Unit) = SplitUnitandStreet(Street,Unit);
}
//returns the split address
return $"{Street},{Unit},{City},{Province},{PostalCode}";
}
static void Main()
{
Console.WriteLine(split_address("3680 KEELE ST, NORTH YORK, ON, M3J1M2"));
}
}
}
Для справки я разрабатываю в VS-коде с расширением C# dev и Dotnet
Подробнее здесь: https://stackoverflow.com/questions/796 ... ble-in-vba