2012-03-25 13 views
1

Ich habe den folgenden SatzOptional Regex für eine Gruppe funktioniert nicht

#bb John can #20 jiang stone [voila] 

ich meine C# regex möchte mich 5 Spiele mit meinen Gruppen

#bb 
John Can 
20 
jiang stone 
voila 

Davon geben die Token in #bb und voila Positionen sind optional.

Ich habe den folgenden Regex-Ausdruck verwendet, der gut in einem Satz funktioniert, der nicht das erste #bb hat - für z.

John can #20 jiang stone [voila] 

gibt mir 4 richtige Token mit dem Ausdruck

@"(.*)#(\d+)(.*\s)(?:\[(.*)\])?" 

Doch wenn ich diese

@"(?:#[a-zA-Z])?(.*)#(\d+)(.*\s)(?:\[(.*)\])?" 
mit

erweitern

Es funktioniert nicht. Die #BB am Anfang des Satzes wird nicht als separate Token abgestimmt - stattdessen bekomme ich ein Spiel wie

b John Can 

ich mehrere Varianten ausprobiert habe aber keine geben Sie mir eine optionale Ergänzung zum ersten # .. Spiel. Was ich will ist, dass dies # {1 oder 2 Zeichen} sein kann und dies optional sein kann. Ich kann es haben, oder es könnte fehlen, in diesem Fall sollte der Rest die Tokens zurückgeben.

Was ist los mit meiner Regex?

Danke für Ihre Hilfe

Antwort

4

Dieses:

#[a-zA-Z] 

bedeutet eine # durch einen Buchstaben einzigen ASCII gefolgt. Sie wollen dies:

#[a-zA-Z]{1,2} 

um ein oder zwei ASCII-Buchstaben zu ermöglichen.

Außerdem folgt aus:

(?:...) 

bedeutet eine non -Einfangfunktion Gruppe. Wenn Sie ein Token in Ihre Ergebnisse zeigen wollen, müssen Sie es in Erfassung Klammern wickeln:

(...) 

Also, es die Zusammenstellung:

@"((?:#[a-zA-Z]{1,2})?)(.*)#(\d+)(.*\s)(?:\[(.*)\])?" 

(Hinweis: Es ist nicht offensichtlich ist, zu Wie Sie das Leerzeichen behandeln möchten, müssen Sie eventuell etwas nach Ihren Bedürfnissen anpassen.Wenn zwischen den ersten beiden Token Leerräume liegen, wird das obige Muster es als Teil des zweiten Tokens behandeln Token.)

+0

Perfekt! Du scheinst ein Gott unter Regexern zu sein, guter Herr. Ich lerne es, kämpfe auf dem Weg. – jeremy

+0

Ich scheine zu schnell reagieren zu müssen - brauche ein bisschen mehr Hilfe. Wenn ich im letzten Abschnitt mehr als 1 Wort verwende - d. H.anstelle von [voila] wenn ich [voila da] sage, dann bricht der letzte Token ... irgendeine Idee, was ich tun sollte, um den ganzen Satz zu erfassen? – jeremy

+0

@jeremy: Eine Möglichkeit zu versuchen ist '(. * \ S)' in '(. *? \ S)' 'zu ändern. Die '*?' -Notation ist wie die '*' Notation, aber während die '*' -Notation "gierig" ist, will sie so viel wie möglich zusammenbringen, und es gibt nur Backtracks, wenn es nötig ist - das '* ? 'Notation ist" widerwillig "- es möchte als * wenig * zusammenpassen, wie es kann. Alternativ, wenn Sie wissen, dass das "Jiang Stone" -Token niemals '[' 'enthalten wird, können Sie' (. * \ S) 'in' ([^ \ [] * \ s) '' so ändern, dass es niemals 'schluckt' [ '. – ruakh