Laden...

Regulärer Ausdruck

Erstellt von Fabian vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.664 Views
Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren
Regulärer Ausdruck

Guten Morgen Forum,

ich habe mal wieder das Problem, einen regulären Ausdruck zu schreiben. Für folgenden Fall brauche ich einen:

Es kommt ein String in der Anwendung an, der so aufgebaut ist:

100 <Parameter1> <ParameterN>

Die Zahl am Anfang ist variabel, schwankt aber nur zwischen 100 und 999. Da würde es mir reichen, einfach auf eine 3-stellige Zahl zu prüfen. Das ist noch nicht das Problem.

Mein Problem sind die Parameter. Ich weiß nicht genau, wie viele davon ankommen. Manchmal ist es einer, manchmal 5 und manchmal gar keiner!
Ich hätte das jetzt gerne so, dass auf die Zahl überprüft wird und die Parameter in Gruppen zur Verfügung stehen. Habe ich also ein Parameter, dann gibt es hinterher zwei Gruppen. Die erste Gruppe ist immer die Zahl, die zweite der erste Parameter.

Habe ich beispielsweise drei Parameter, habe ich vier Gruppen und so weiter. An diesen variablen Gruppen scheitert es gerade.

Kann mir da jemand bei helfen?

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Fabian,

ich gehe mal davon aus, dass die Paramter beliebige, durch ein (oder mehrere) Leerzeichen getrennte Zeichenfolgen sind. Dann hat das etwas die gleiche Schwierigkeit wie auf die 3-stellige Zahl zu prüfen. Also kein Problem.

Das einzige ist, dass du nachher nicht die Guppen verwenden kannst, sondern eine Ebene tiefer steigen musst, zu den Captures (Group.Captures Property). Aber der Pattern selbst ist doch simpel. Den kriegst du alleine hin.

herbivore

Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren

Hallo heribvore,

Du kannst mich ja schon gut einschätzen 🙂.

Prinzipiell hast Du aber Recht. Eigentlich sollte ich das alleine hinbekommen. Folgenden RegEx habe ich bis jetzt geschrieben:

^([0-9]{3})( \\w+)?$

Er matched jetzt auch schon fast richtig. Besteht der String nur aus der Zahl, ist er richtig. Folgt dahinter ein Leerzeichen, ist er falsch. So soll es auch sein. Folgt nach dem Leerzeichen der erste Parameter, ist es wieder richtig. Auch wunderbar!

Habe ich dann aber hinter dem ersten Parameter ein Leerzeichen, dann soll er wieder nicht matchen, da der zweite Parameter fehlt. Folgt hinter dem Leerzeichen der zweite Parameter, dann soll er wieder matchen.

Das bekomme ich noch nicht hin, also dass die Parameter beliebig hintereinander folgenden dürfen.

Was fehlt mir bzw. was mache ich falsch?

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Fabian,

@"^([0-9]{3})( \w+)*$"

herbivore

PS: [0-9]{3} geht auch kürzer: \d\d\d 🙂

Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren

Hallo herbivore,

aaargh! An das Sternchen habe ich gar nicht gedacht. Ich danke Dir. Jetzt läuft es ohne Probleme.

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren

Hallo,

so, jetzt habe ich doch noch eine Frage bzw. ein Problem. Anscheinend werden die Gruppen nicht richtig aufgelöst.

Bei dem String "100 Hallo Du" ist die erste Gruppe alles, also der ganze String, die zweite Gruppe ist die "100" und die dritte Gruppe das "Du". Allerdings sollte es so sein, dass die dritte Gruppe das "Hallo" und die vierte Gruppe das "Du" ist.

Muss ich da noch was an den Klammern umstellen oder was läuft schief?

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Fabian,

die dritte Gruppe matcht auf Hallo und Du. Du musst - wie ich schon schrieb - die Captures statt denn Gruppen verwenden.

herbivore

PS: Eigentlich interessiert man sich immer nur für die Captures. Dass man mit m.Groups _ meist das Capture bekommt, das man will, liegt an einem Trick:

Group inherits from Capture so the last substring captured can be accessed directly. (That is, the Group instance itself is equivalent to the last item of the collection returned by the Captures property).

Eigentlich müsste man m.Groups _.Captures[j], um an die Captures zu kommen. m.Groups _ ist also nur eine Abkürzung für m.Groups _.Captures[m.Groups _.Captures.Length-1].

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Fabian,

was mir gerade noch einfällt. Es ist keine gute Idee, über die Nummern der Gruppen zuzugreifen. Dann muss man alle Nummern prüfen/anpassen, wenn man später mal Klammern hinzufügen oder entfernen will. Verwende besser benannte Gruppen:

@"^(?<num>\d\d\d)( (?<param>\w+))*$"

Der Zugriff auf eine benannte Gruppe läuft dann über den Namen, also z.B. m.Groups ["param"].

herbivore

Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren

Hallo herbivore,

danke für die Antwort. Da habe ich jetzt leider nur ein Problem, da ich das Pattern in Java benutzen will. Entschuldige, dass ich das nicht von Anfang an gesagt habe. Ich dachte, die beiden Klassen für die Matches wären gleich mächtig.

Anscheinend habe ich in Java leider keine Möglichkeit, an die Captures zu kommen 😦.

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Fabian,

ich denke, da hast du jetzt ein Problem. Da es in Java wohl gar keine Group-Klasse gibt, sondern Matcher.group () direkt einen String liefert und auch die anderen Methoden von Matcher nicht so aussehen, als würden sie hier helfen, geht das wohl nicht.

Workaround könnte sowas sein wie @"^([0-9]{3})( \w+)?( \w+)?( \w+)?( \w+)?( \w+)?( \w+)?$"

herbivore

PS: Den Tipp, mit den benannten Gruppen, kannst du wohl in Java auch knicken.

Fabian Themenstarter:in
1.985 Beiträge seit 2004
vor 18 Jahren

Hallo herbivore,

ja, da habe (hatte) ich tatsächlich ein Problem. Ich habe jetzt einen RegEx genommen, der die Gruppen statisch angibt, also so wie Du es vorgeschlagen hast.

Damit funktioniert es gut.

Danke noch mal für Deine Hilfe!

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

563 Beiträge seit 2004
vor 18 Jahren

\d{3} wäre noch ein zeichen kürzer als \d\d\d (wenn wir schon beim kürzen sind) g