2012-04-08 4 views
0

Итак, у меня есть регулярное выражение, и мне нужно найти его в многострочной строке. Это строка, которую я использую:Regex останавливается после сопоставления первой строки

Device Identifier:  disk0 
Device Node:    /dev/disk0 
Part of Whole:   disk0 
Device/Media Name:  OCZ-VERTEX2 Media 

Volume Name:    Not applicable (no file system) 

Mounted:     Not applicable (no file system) 

File System:    None 

Content (IOContent):  GUID_partition_scheme 
OS Can Be Installed:  No 
Media Type:    Generic 
Protocol:     SATA 
SMART Status:    Verified 

Total Size:    240.1 GB (240057409536 Bytes) (exactly 468862128 512-Byte-Blocks) 
Volume Free Space:  Not applicable (no file system) 
Device Block Size:  512 Bytes 

Read-Only Media:   No 
Read-Only Volume:   Not applicable (no file system) 
Ejectable:    No 

Whole:     Yes 
Internal:     Yes 
Solid State:    Yes 
OS 9 Drivers:    No 
Low Level Format:   Not supported 

В основном мне нужно разделить каждую строку на две группы с двоеточием в качестве разделителя. Регулярное выражение, я использую это:

@"([A-Za-z0-9\(\) \-\/]+):([A-Za-z0-9\(\) \-\/]+).*" 

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

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

Любая помощь приветствуется.

+3

Можете ли вы включить код C#, который вы используете? –

+0

Я буду, когда вернусь к компьютеру. –

ответ

2

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

var rgx = new System.Text.RegularExpressions.Regex(@"(?<Key>[^:\r\n]+):([\s]*)(?<Value>[^\r\n]*)"); 
    foreach (var match in rgx.Matches(str).Cast<Match>()) 
    { 
     Console.WriteLine("{0}: {1}", match.Groups["Key"].Value, match.Groups["Value"].Value); 
    } 

Для удовольствия, это превращает все это в простом в использовании словаря:

var dictionary = rgx.Matches(str).Cast<Match>().ToDictionary(match => match.Groups["Key"].Value, match => match.Groups["Value"].Value); 
+0

Это именно то, что мне нужно. Добавленный словарный код достиг точно того, что я хотел в краткой и элегантной форме. Благодаря! –

0

Проблема с вашим Regex является последней. *. Он соответствует \ r \ n, и поэтому вся строка останова сопоставляется.

0

Вместо этого я предлагаю использовать String.Split. Если предположить, что все ключи уникальны:

string[] lines = str.Split(new char[] { '\r', '\n'} , 
    StringSplitOptions.RemoveEmptyEntries); 

Dictionary<string, string> dict = lines.ToDictionary(
    line => line.Split(':').First(), 
    line => line.Split(new char[] { ':' }, 2).Last().Trim()); 
0

Если вы используете опцию регулярных выражений SingleLine то .* пока сопрягать все остальные строки и так есть только одно совпадение.

SingleLine говорит регулярное выражение парсер дополнительно принимать подачи строки (т.е. \n) при выполнении матча на .

Вы даже нужно. * Вообще?

Alternative можно использовать

^([A-Za-z0-9\(\) \-\/]+):([A-Za-z0-9\(\) \-\/]+)$ 

Aslong, как вы используете его с опцией регулярных выражений MultiLine сделать^$ начало и конец строки, а не строки соответствия.

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