2016-04-19 5 views
0

У меня есть следующая строкаRegex групповому почтовый индекс, город и государство

«98225-2077 Bellingham WA»

мне нужно использовать Regex отделить почтовый индекс, город и государство. группам следует вернуть (98225-2077) (Беллингем) и (WA). Состояние является необязательным и всегда будет в конце и будет состоять из двух верхних символов.

Я могу отфильтровать следующие действия с помощью регулярных выражений

Индекс: (^([\S]+-)?\d+(-\d+)?) - Группа [1]
Город: ((^([\S]+-)?\d+(-\d+)?)\s)?(\S.*) = Группа [5].

Может ли быть одно регулярное выражение, чтобы отфильтровать все три, используя одно и то же регулярное выражение, и вернуть пустое, если состояние там отсутствует?

+1

название города также может быть более одного слова. Пример Нью-Дели. – SJMan

+1

Отлично ... спасибо, что сообщили мне об этом сейчас –

+0

Единственный способ разбора - это регулярное выражение, которое хранится в Db в соответствии с дизайном – SJMan

ответ

0

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

string address = "98225-2077 Bellingham WA"; 
string[] tokens = address.Split(' '); 

string city = ""; 
for (int i=1; i < tokens.Length-1; i++) 
{ 
    if (i > 1) 
    { 
     city += " "; 
    } 
    city += tokens[i]; 
} 

Console.WriteLine("zip code: {0}", tokens[0]); 
Console.WriteLine("city: {0}", city); 
Console.WriteLine("state: {0}", tokens[tokens.Length-1]); 
0

Легко!

^([\d-]+)\s+(.+?)\s*([A-Z]{2})?$ 

https://regex101.com/r/tL4tN5/1

Объяснение:

  1. ^([\d-]+): ^ для самого начала строки. \d для цифр
  2. \s+(.+?)\s*: Получить что-нибудь в середине между почтовым индексом и состоянием
  3. ([A-Z]{2})?$: {2} означает 2 символа в заданном диапазоне [A-Z]. ? означает, что он существует 1 или 0 раз.
+0

Состояние может или не может быть. Я работаю C# – SJMan

+0

Yup, он может работать без состояния. Я немного обновляю регулярное выражение, чтобы быть более точным. Пожалуйста ознакомтесь –

0

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

Non-регулярное выражение решения:

/// <summary> 
/// Split address into ZIP, Description/Street/anything, [A-Z]{2} state 
/// </summary> 
/// <returns>null if no space is found</returns> 
public static List<string> SplitZipAnyStateAddress(this string s) 
{ 
    if (!s.Contains(' ')) return null; 
    var zip = s.Substring(0, s.IndexOf(' ')); 
    var state = s.Substring(s.LastIndexOf(' ') + 1); 
    var middle = s.Substring(zip.Length + 1, s.Length - state.Length - zip.Length - 2); 
    return state.Length == 2 && state.All(p => Char.IsUpper(p)) ? 
     new List<string>() { zip, middle, state } : 
     new List<string>() { zip, string.Format("{0} {1}", middle, state) }; 
} 

Результаты:

StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellingham WA"); 
// => [0] 98225-2077 [1] Bellingham [2] WA 
StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellin gham"); 
// => [0] 98225-2077 [1] Bellin gham 
StringRegUtils.SplitZipAnyStateAddress("98225-2077 New Delhi CA"); 
// => [0] 98225-2077 [1] New Delhi [2] CA 

REGEX

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

^(?<zip>\d+-\d+)\s+(?<city>.*?)(?:\s+(?<state>[A-Z]{2}))?$ 

Посмотреть regex demo

Детали:

  • ^ - начало строки
  • (?<zip>\d+-\d+) - 1+ цифры следуют с - следуют с 1+ цифр
  • \s+ - 1+ пробельные
  • (?<city>.*?) - кроме символа новой строки как можно вплоть до
  • (?:\s+(?<state>[A-Z]{2}))? 0+ символов - необязательные (1 или 0) вхождения
    • \s+ - 1+ пробельных
    • (?<state>[A-Z]{2}) - ровно 2 заглавных букв ASCII
  • $ - конец строки