2009-03-16 22 views
0

Ich habe einen Text wie „Artikelnummer - Artikelbeschreibung“ zB „13-40 - Computertastatur“, die ich in eine Artikelnummer und Artikelbeschreibung teilen möchten.Reguläre Ausdrücke und „Gruppen“

Ist dies möglich mit 1 regulären Ausdruck, oder brauche ich 2 (eine für Artikel und eine für Beschreibung)?

Ich kann nicht arbeiten, wie man „Gruppe“ sie - wie die Artikelnummer dies sein kann und die Beschreibung kann das sein, ohne es zu denken, dass alles, was ist die Artikelnummer. ZB:

(\w(\w|-|/)*\w)-.* 

passt alles als 1 Übereinstimmung.

Dies ist der Code Ich verwende:

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

Um Poster: Ich glaube, er will einen regulären Ausdruck finden, die die Ergebnisse produziert er will. Er kann nur den regulären Ausdruck (hier RegExString) ändern, nicht den Rest des Codes. (Meine Antwort bietet eine getestete Lösung.) – strager

+0

Ehh, vergiss es. Anscheinend lag ich falsch (da Samuels Antwort angenommen wurde). – strager

Antwort

4

Aus dem Code, den Sie gepostet haben, verwenden Sie Regex falsch. Sie sollten ein Regex-Muster haben, das dem gesamten Produkt entspricht, und die Captures innerhalb des Matches verwenden, um die Nummer und die Beschreibung zu extrahieren.

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

Hier ist ein regulärer Ausdruck, in Ruby arbeitet - nicht sicher, ob es Unterschiede in C# regexp sind:

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

Dies entspricht der gesamten "13-40 - Computer Keyboard" als 1 String in C#. –

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

Gruppe 1 enthält die Positionsnummer und Gruppe 2 enthält die Beschreibung.

+0

Dies entspricht der gesamten "13-40 - Computer Keyboard" als 1 String in C#. –

+0

@dan gibson, das ist wahr. Es soll das tun. Die resultierenden Teile sind in Ihren zwei Gruppen. – strager

0

Wenn Ihr Text immer durch einen Bindestrich geteilt wird und Sie nicht mit Bindestrichen in den Daten umgehen müssen, müssen Sie Regex nicht verwenden.

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

Der Benutzer kann eine Regex für jedes Format liefern, also muss ich eine Regex verwenden. –

1

Die Antwort von CaffeineFueled ist korrekt für C#.

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

Ergebnisse:

13-40
Computertastatur

+0

Die beiden geposteten Regex-Muster funktionieren beide, der Fragesteller hat es einfach nicht richtig benutzt (siehe meine Antwort). – Samuel

0

Sie scheinen keine Gruppen wollen übereinstimmen, aber mehrere Übereinstimmungen haben.

Vielleicht wird dies tun, was Sie wollen?

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

Split up:

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

Das ist nicht so elegant wie CaffineFueled Antwort, aber vielleicht einfacher für einen regulären Ausdruck Anfänger zu lesen.

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); 

oder sogar besser lesbar:

String RegExString = "(\d*-\d*) - (.*)";