2011-10-07 2 views
0

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

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

Это код, который я использую для разбивки данных.

 using (StreamReader sr = new StreamReader(file)) 
     { 
      string line; 
      line = sr.ReadToEnd(); 
      string[] parts = Regex.Split(line, @"(?=PA11)"); 

      List<string> parameterList = new List<string>(parts); 

      foreach (string s in parameterList) 
      { 
       listBox1.Items.Add(s); 
      } 
     } 

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

*newline* 
LINE 000001 000001 TEST A B TEST OUTPUT *More Lines*     
LINE 000002 000002 TEST A B TEST OUTPUT *More Lines*     

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

ответ

0

Мне кажется, что это не вставка newline, но пустой ввод. Ваше регулярное выражение соответствует самому началу ввода, потому что первая строка начинается с PA11, и она не потребляет никаких символов, поэтому первый элемент массива parts представляет собой пустую строку. Вы должны быть в состоянии предотвратить это, заставляя регулярное выражение, чтобы потреблять некоторые символы, такие как символ новой строки, предшествующей PA11 линии:

string[] parts = Regex.Split(line, @"[\r\n]+(?=PA11)"); 

...или убедившись, что он не соответствует если нет новой строки перед тем PA11:

string[] parts = Regex.Split(line, @"(?<=[\r\n])(?=PA11)"); 
+0

Я попробовал первый оператор Regex и, похоже, работает правильно. Я просто понял, что я оставил важную информацию. Перед любым из полей PA11 есть 3 строки заголовка, но это, похоже, не влияет на заявление, которое вы мне дали. Единственная проблема, которую я должен решить, заключается в том, что в конце файла есть одна дополнительная строка в конце, после того как я поместил файл обратно после редактирования. Спасибо за помощь. – almostProgramming

+0

Извините за чрезмерные комментарии, но я нашел простое исправление для дополнительной новой строки, используя RemoveAt (list.Count - 1). Еще раз спасибо. – almostProgramming

1

Если ваша потребность такая простая, не используйте REGEX.

using (StreamReader sr = new StreamReader(file)) 
{ 
    string line = sr.ReadLine(); 
    while(line != null){ 
    if(line.StartsWith("PA11")){ 
     string[] parts = line.Split(" "); 
     List<string> parameterList = new List<string>(parts); 

     foreach (string s in parameterList) 
       listBox1.Items.Add(s); 
     } 
    } 
} 
+0

Хорошая идея. Несколько вещей. Во-первых, вместо использования 'StreamReader' просто используйте' foreach (var line в File.ReadLines (файл)) '. Во-вторых, зачем создавать 'List ' из массива 'parts', когда вы можете просто написать' foreach (var s по частям) '? –

+0

Этот код, похоже, не работает для меня. Когда я запускаю его, программа просто зависает. – almostProgramming

+0

Я лениво использовал существующий код, главное было использовать метод .StartsWith (..) вместо регулярного выражения. –

0

Почему бы не использовать string.split? string [] parts = line.split ("PA11") .. вы можете снова вставить деминератор в каждую часть.

0

Причина, по которой он создает пустой элемент [0], есть, вероятно, пробел (новая строка) в начале строки.
Ниже будет работать, код протестирован здесь->http://www.ideone.com/tsOlI (я не эксперт .NET)

строка [] = части Regex.Split (линия, @ "(?=(?<!^\s*)PA11)");

Expanded:

(?=   # look ahead, we're at the first 'PA11' 
    (?<!^\s*)  # before its ok, there can't be '^\s*' before us 
    PA11   # ok, this 'PA11' is good to split 
)   # end look ahead 

Учтите, что если есть что-нибудь другое, кроме пробела перед первым PA11,
это создаст [0] элемент с этим блоком.

Это можно было бы сделать немного более значимым в матча все контекста с чем-то вроде этого:

(?:^\s*|(?<=\n))\s*(PA11.*?)(?=\n+PA11|$)
использования одного модификатора линии или изменить .*? к [\S\s]*?

Это будет соответствовать только с начала от блока до следующего начала (или конца строки) и полоски пробельных символов остаточной границы.

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