2013-06-19 2 views
0
вход

Sample есть (обратите внимание, что это строка из одной строки, я использовал цитату здесь, чтобы сделать его более удобным для чтения):разбираемой строки в нужный выход

Уровень 1/129/1 Murray Ave & 15А & B ERICA AVENUE & 12 HARVEY STREET VICTORIA STREET & 3/56 ST LEONARDS ST, MOSMAN PARK (John). 78/10 Wellington St Мосман Park (Рэмбо)

Мой выходной ток:

1/129/1 - Murray - Ave - 
15A - - - 
B - ERICA - AVENUE - 
12 - HARVEY - STREET - 
34 - VICTORIA - STREET - 
3/56 - ST LEONARDS - ST - MOSMAN PARK 
78/10 - WELLINGTON - ST - MOSMAN PARK 

Желаемый результат:

1/129/1 - Murray - Ave - 
15A - ERICA - AVENUE - 
15B - ERICA - AVENUE - 
12 - HARVEY - STREET - 
34 - VICTORIA - STREET - 
3/56 - ST LEONARDS - ST - MOSMAN PARK 
78/10 - WELLINGTON - ST - MOSMAN PARK 

Если первое свойство содержит только номер, то должен наследовать информацию из следующей записи, и если следующий номер записи содержит только букву, которую она показывает назад, наследует номер предыдущей записи, например:

15A - Erica - Avenue 
    15B - Erica - Avenue 

Что дает мне желаемый вывод выше, как я могу его архивировать?

Вот мой код (Примечание: суффиксы является List<string>):

static void Main(string[] args) 
{ 
    List<ResultData> result = new List<ResultData>(); 
    string myColumn = "Level 1/129/1 Murray Ave & 15A&B ERICA AVENUE & 12 HARVEY STREET & 34 VICTORIA STREET & 3/56 ST LEONARDS ST, MOSMAN PARK (John). 78/10 WELLINGTON ST MOSMAN PARK (Rambo)"; 
    // dot replaced with & as they are to be split 
    myColumn = myColumn.Replace('.', '&'); 
    // I don't need the Level word which means 
    // each property starts with numbers now 
    myColumn = myColumn.Replace("Level", ""); 
    // Removes anything in between parentheses and the parentheses 
    myColumn = RemoveBetween(myColumn, '(', ')'); 

    string[] splitResult = myColumn.Split('&');  
    foreach (string item in splitResult) 
    { 
     string property = item.Trim(); 
     if (property.IndexOf(' ') > 0) 
     { 
      string area = string.Empty; 
      string locationType = string.Empty; 
      string number = property.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).First(); 
      property = property.Replace(number, "").Trim(); 

      // When comma is present, area is always the last 
      // and locationType always before it 
      if (property.IndexOf(',') > 0) 
      { 
       area = property.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim(); 
       property = property.Replace(area, "").Replace(",", "").Trim(); 

       locationType = property.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim(); 
       property = property.Replace(" " + locationType, "").Trim(); 
      } 
      else 
      { 
       // When comma is not present I have to check 
       // if the string contains a given street suffix 
       // and pick up from there 
       string found = suffixes.Find(x => property.Trim().Contains(" " + x, StringComparison.OrdinalIgnoreCase)); 
       if (!string.IsNullOrEmpty(found)) 
        found = " " + found; 
        // need the space otherwise it will delete 
        // places like ST LEONARD. 

       locationType = property.Substring(property.ToLower().IndexOf(found.ToLower()), found.Length).Trim(); 

       int total = property.ToLower().IndexOf(found.ToLower()) + found.Length; 
       if (property.ToLower().IndexOf(found.ToLower()) > 0 && total < property.Length) 
        area = property.Substring(total, property.Length - total).Trim(); 

       property = property.Replace(",", "").Trim().Replace(locationType, "").Trim(); 
       if (!string.IsNullOrEmpty(area)) 
        property = property.Replace(area, "").Trim(); 
      } 

      string name = property; 
      result.Add(new ResultData() { Number = number, Name = name, LocationType = locationType, Area = area }); 
     } 
     else 
     { 
      result.Add(new ResultData() { Number = property }); 
     } 
    } 

    string save = string.Empty; 
    foreach (ResultData item in result) 
    { 
     Console.WriteLine(item.Number + " - " + item.Name + " - " + item.LocationType + " - " + item.Area); 
     save += item.Number + " - " + item.Name + " - " + item.LocationType + " - " + item.Area + Environment.NewLine; 
    } 
    System.IO.File.WriteAllLines(@"save.txt", save.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)); 

    Console.WriteLine(Environment.NewLine + "Press any key to leave..."); 
    Console.ReadKey(); 
} 

/// <summary> 
/// Remove from the string the pattern and what is in between it 
/// more format double space to single 
/// </summary> 
static string RemoveBetween(string s, char begin, char end) 
{ 
    Regex regex = new Regex(string.Format("\\{0}.*?\\{1}", begin, end)); 
    return new Regex(" +").Replace(regex.Replace(s, string.Empty), " "); 
} 

public static bool Contains(this string source, string toCheck, StringComparison comp) 
{ 
    return source.IndexOf(toCheck, comp) >= 0; 
} 

Если вы знаете, что я могу сделать, чтобы улучшить код выше хотелось бы знать, как хорошо, напишите мне комментарий.

+0

Просто, чтобы подтвердить, вы ищете общее решение, которое будет работать для любого жала на основе этих правил? – psubsee2003

+0

У вас есть контроль, чтобы изменить ввод –

+0

@ psubsee2003 У меня есть только 1 проблема, которую я не могу решить прямо сейчас, см. «Мой текущий вывод:» и «Желаемый вывод:« Я не знаю, как заполнить до 15А с данными из следующей записи и заполнить номер 15 данными для получения желаемого результата. Проще говоря, если в записи есть только номер, который должен наследовать данные из следующей записи, и если следующая запись имеет только букву на номере, она должна наследовать номер предыдущей записи. – Guapo

ответ

0

Этот код должен делать эту работу:

string prevString = ""; 
    string[] splitResult = myColumn.Split('&');  
    foreach (string item in splitResult) 
    { 
     string property = item.Trim(); 
     if (property.IndexOf(' ') > 0) 
     { 
      string area = string.Empty; 
      string locationType = string.Empty; 
      string number = property.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).First(); 
      property = property.Replace(number, "").Trim(); 

      // When comma is present, area is always the last 
      // and locationType always before it 
      if (property.IndexOf(',') > 0) 
      { 
       area = property.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim(); 
       property = property.Replace(area, "").Replace(",", "").Trim(); 

       locationType = property.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim(); 
       property = property.Replace(" " + locationType, "").Trim(); 
      } 
      else 
      { 
       // When comma is not present I have to check 
       // if the string contains a given street suffix 
       // and pick up from there 
       string found = suffixes.Find(x => property.Trim().Contains(" " + x, StringComparison.OrdinalIgnoreCase)); 
       if (!string.IsNullOrEmpty(found)) 
        found = " " + found; 
        // need the space otherwise it will delete 
        // places like ST LEONARD. 

       locationType = property.Substring(property.ToLower().IndexOf(found.ToLower()), found.Length).Trim(); 

       int total = property.ToLower().IndexOf(found.ToLower()) + found.Length; 
       if (property.ToLower().IndexOf(found.ToLower()) > 0 && total < property.Length) 
        area = property.Substring(total, property.Length - total).Trim(); 

       property = property.Replace(",", "").Trim().Replace(locationType, "").Trim(); 
       if (!string.IsNullOrEmpty(area)) 
        property = property.Replace(area, "").Trim(); 
      } 

       string name = property; 
       if (prevString != "") 
       { 
        result.Add(new ResultData() { Number = prevString, Name = name, LocationType = locationType, Area = area }); 
        string numbersFromString = new String(number.Where(x => x >= '0' && x <= '9').ToArray()); 
        if (numbersFromString == "") 
        { 
         string numbersFromString2 = new String(prevString.Where(x => x >= '0' && x <= '9').ToArray()); 
         result.Add(new ResultData() { Number = (int)numbersFromString2 + number, Name = name, LocationType = locationType, Area = area }); 
        } 
        else 
        { 
         result.Add(new ResultData() { Number = number, Name = name, LocationType = locationType, Area = area }); 
        } 

       } 
       else 
       { 
        result.Add(new ResultData() { Number = number, Name = name, LocationType = locationType, Area = area }); 
       } 


       prevString = ""; 
     } 
     else 
     { 
      prevString = property; 
     } 
    } 
-1

Похоже, каждая строка начинается с пробела, а затем числового.

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

 var myString = "Line: 12 this way 23 that way 34 no way".ToCharArray(); 
     var firstDigitFound = false; 
     for (int i = 0; i < myString.Length; i++) 
     {     
      var isNumber = char.IsNumber(myString[i]); 
      if (isNumber && i > 0 && !firstDigitFound) 
      { 
       firstDigitFound = true; 
       myString[i - 1] = '|'; 
      } 
      else { firstDigitFound = false; } 
     } 

     var myNewArray = new string(myString).Split('|'); 
+0

Дэвид, это не то, что нужно, и нет, что бы испортило все номера/записи. – Guapo

+0

очень суровый для отметки, когда кто-то пытается помочь. Он также помещает каждый номер в новую строку, как показано в вашем примере. Это также должен быть первый шаг в вашей обработке. – David

+0

Оцените свое обновление, но я до сих пор не понимаю, почему вы пытаетесь поместить каждый номер в новую строку, чего я не хочу. Внимательно посмотрите ** «Мой текущий выход» ** и ** «Требуемый вывод» ** – Guapo

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