2014-09-30 4 views
0

У меня есть приложение Xamarin Forms, которое использует Xamarin. Мобильный на платформах, чтобы получить текущее местоположение, а затем установить текущий адрес. Адрес возвращается в формате строки с разрывами строк.Как извлечь компоненты адреса из строки?

Адрес может выглядеть следующим образом:

111 Mandurah Tce 
Mandurah WA 6210 
Australia 

или

The Glades 
222 Mandurah Tce 
Mandurah WA 6210 
Australia 

У меня есть этот код, чтобы разбить его на почтовый адрес (включая номер), пригород, штат и почтовый индекс (не очень элегантный, но он работает)

string[] lines = address.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); 
List<string> addyList = new List<string>(lines); 
int count = addyList.Count; 
string lineToSplit = addyList.ElementAt(count - 2); 
string[] splitLine = lineToSplit.Split(null); 
List<string> splitList = new List<string>(splitLine); 

string streetAddress = addyList.ElementAt (count - 3).ToString(); 
string postCode = splitList.ElementAt(2); 
string state = splitList.ElementAt(1); 
string suburb = splitList.ElementAt(0); 

Я хотел бы указать номер улицы, а в предыдущей но это лучший способ сделать это, учитывая количество может быть Lot 111 (нужно только захватить 111, а не слово LOT), или 123A или 8/123 - и иногда что-то как 111-113 также возвращен

Я знаю, что я могу использовать регулярное выражение и искать все возможные комбо, но есть ли элегантный встроенный тип решения, прежде чем я начну писать более грязный код (и я знаю, что выше код не особенно устойчив)?

ответ

0

Эти простые регулярные выражения будут составлять для многих типов форматов адресов, но вы рассмотрели все возможные варианты, такие как:

PO Box 123 suburb state post_code 
Unit, Apt, Flat, Villa, Shop X Y street name 
7C/94 ALISON ROAD RANDWICK NSW 2031 

и просто получить номер. Вам также придется иметь дело со всеми возможными типами улиц, такими как Lane, Road, Place, Av, Parkway.

Тогда уличные типы, такие как:

12 Grand Ridge Road suburb_name 

Это может быть истолковано как улица = «Гранд-Ридж» и пригорода = «Дорога suburb_name», поскольку Ридж также допустимый тип улицы.

Я проделал большую работу в этой области и нашел огромное количество допустимых шаблонов адресов, поскольку простые регулярные выражения не помогли решить проблему с большими объемами данных.

Я решил разобраться с этим парсером http://search.cpan.org/~kimryan/Lingua-EN-AddressParse-1.20/lib/Lingua/EN/AddressParse.pm, чтобы решить эту проблему. Он был первоначально написан для австралийских адресов, поэтому он должен хорошо работать для вас.

+0

Это именно то, что нужно. Спасибо – user1667474

+0

ссылка, которую вы предоставляете, больше не работает –

+0

Спасибо, это должно быть ссылка на последнюю версию http://search.cpan.org/~kimryan/Lingua-EN-AddressParse/ –

0

Вы можете проверить, начинается ли контент с номера для каждой записи в splitLine.

string[] splitLine = lineToSplit.Split(addresseLine); 

var streetNumber = string.empty; 
foreach(var s in splitLine) 
{ 
    //Get the first digit value 
    if (Regex.IsMatch(s, @"^\d")) 
    { 
     streetNumber = s; 
     break; 
    }  
} 

// Deal с пустым значением другой способ

Console.WriteLine("My streetnumber is " + s) 
+0

Спасибо всем вам за ваши ответы. Все приведенное выше работает для данных примеров. Подумав об этом больше, я думаю, что мне нужно что-то первое захватить первое число до последнего пробела перед последним числовым. Таким образом, он будет захватывать 123A или 4/456 или 111-113, и если бы это было так, я мог бы их разделить 4 и 456. Затем я мог бы получить адрес улицы после пробела после последнего числа. – user1667474

0

Да, я думаю, вы должны определить, что будет работать.

Если:

  • всегда в адресной строке, и она всегда должна начинаться с цифры
  • ничего другого в этой строке может начинаться с цифры (или если что-то еще делает вы знаете, какой всегда приходит, в каком порядке, т. е. код, указанный ниже, всегда будет работать, если номер улицы всегда будет первым)
  • Вы хотите, чтобы каждый непрерывный символ не был пробелом (это - и \ примеры предлагают это мне)

Тогда это может быть столь же просто, как:

var regx = new Regex(@"(?:\s|^)\d[^\s]*"); 
var mtch = reg.Match(addressline); 

Вы бы своего рода придется просеять и посмотреть, если какой-либо из этих предположений сломаны.

1

Регулярное выражение может фиксировать части матча по группам. Каждая скобка () определяет группу.

([^\d]*)(\d*)(.*) 

Для "Lot 222 Mandurah Tce" это возвращает из следующих групп

Группа 0: "Lot 222 Mandurah Tce" (входная строка)
Группа 1: "Lot "
Группа 2: "222"
Группа 3: " Mandurah Tce"

Пояснение :

[^\d]* Любое число (включая 0) любого символа, за исключением цифр.
\d* Любое число (включая 0) цифр.
.* Любое число (включая 0) любого символа.

string input = "Lot 222 Mandurah Tce"; 
Match match = Regex.Match(input, @"([^\d]*)(\d*)(.*)"); 
string beforeNumber = match.Groups[1].Value; // --> "Lot " 
string number = match.Groups[2].Value;  // --> "222" 
string afterNumber = match.Groups[3].Value; // --> " Mandurah Tce" 

Если группа не обнаруживает соответствия, match.Groups[i] возвращает пустую строку ("") для этой группы.

+0

Так много лет спустя, и это все еще полезно! Он сделал именно то, что я искал! Благодаря! – AxleWack

Смежные вопросы