2009-03-16 3 views
0

У меня есть текст типа «номер позиции - описание элемента», например «13-40 - компьютерная клавиатура», который я хочу разделить на номер позиции и описание элемента.Регулярные выражения и «группы»

Возможно ли это с 1 регулярным выражением, или мне нужно 2 (один для элемента и один для описания)?

Я не могу понять, как «сгруппировать» его - как и номер позиции, это может быть и описание, и это может быть без него, не думая, что все - номер позиции. Например:

соответствует всем, что соответствует одному.

Это код, я использую:

Regex rx = new Regex(RegExString, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
MatchCollection matches = rx.Matches("13-40 - Computer Keyboard"); 
Assert.AreEqual("13-40", matches[0].Value); 
Assert.AreEqual("Computer Keyboard", matches[1].Value); 
+0

плакатов: Я считаю, что он хочет найти регулярное выражение, которое производит результаты, которые он хочет. Он может изменять только регулярное выражение (RegExString здесь), а не остальную часть кода. (Мой ответ дает протестированное решение.) – strager

+0

Ehh, nevermind. Видимо, я был неправ (как был принят ответ Сэмюэля). – strager

ответ

4

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

string RegExString = @"(?<number>[\d-]+)\s-\s(?<description>.*)"; 
Regex rx = new Regex(RegExString, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
Match match = rx.Match("13-40 - Computer Keyboard"); 
Debug.Assert("13-40" == match.Groups["number"].Value); 
Debug.Assert("Computer Keyboard" == match.Groups["description"].Value); 
1

Вот регулярное выражение, которое работает в Ruby, - не уверен, что если есть какие-либо различия в C# регулярное выражение:

/^([\d\-]+) \- (.+)$/ 
+0

Это соответствует всей «13-40 - компьютерной клавиатуре» как 1 строка в C#. –

1
([0-9-]+)\s-\s(.*) 

Группа 1 содержит номер позиции, а группа 2 содержит описание.

+0

Это соответствует всей «13-40 - компьютерной клавиатуре» как 1 строка в C#. –

+0

@ dan gibson, Это правда. Он должен это сделать. Полученные части находятся в двух группах. – strager

0

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

string[] itemProperties = item.Split(new string[] { "-" }); 
itemProperties = itemProperties.Select(p => p.Trim()); 
Item item = new Item() 
{ 
    Number = itemProperties[0], 
    Name = itemProperties[1], 
    Description = itemProperties[2] 
} 
+0

Пользователь может предоставить регулярное выражение для соответствия любому формату, поэтому мне нужно использовать регулярное выражение. –

1

Ответ CaffeineFueled подходит для C#.

Match match = Regex.Match("13-40 - Computer Keyboard", @"^([\d\-]+) \- (.+)$"); 
Console.WriteLine(match.Groups[1]); 
Console.WriteLine(match.Groups[2]); 

Результаты:

13-40
Компьютерная клавиатура

+0

Два опубликованных шаблона регулярных выражений оба работают, искатель просто не использовал его правильно (см. Мой ответ). – Samuel

0

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

Возможно, это сделает то, что вы хотите?

(:^.+(?=(-))|(?<=(-)).+$) 

разделиться:

(:   Used to provide two possible matches 
^.+   Match item ID text 
(?=(-)) Text must be before " - " 
|   OR 
(?<=(-)) Test must be after " - " 
.+$   Match description text 
) 
0

Это не так элегантно, как ответ CaffineFueled, но, может быть, легче читать для начинающих регулярных выражений.

String RegExString = "(\d*-\d*)\s*-\s*(.*)"; 
Regex rx = new Regex(RegExString, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
MatchCollection matches = rx.Matches("13-40 - Computer Keyboard"); 
Assert.AreEqual("13-40", matches[0].Value); 
Assert.AreEqual("Computer Keyboard", matches[1].Value); 

или даже более читаемым:

String RegExString = "(\d*-\d*) - (.*)"; 
Смежные вопросы