| 

.NET C# Java Javascript Exception

1
Hallo Codekicker

Ich stehe mal wieder aufm Schlauch.... und hoffe mir kann jemand mit dem folgenden Regex-Pattern helfen.

^[^\.]+[BbAaTtPp\.]+[^\.]$

So sieht mein Pattern im Moment aus. Aber es tut einfach nicht was es soll. Was es leisten soll ist:
Die Zeichenkette darf nicht mit einem Punkt beginnen oder enden.
Die Zeichenkette darf insgesamt nur aus den Zeichen B, b, A, a, T, t, P, p und . (der Punkt darf nur als Trennzeichen verwendet werden) bestehen.
Ausserdem müssten die gültigen Zeichen (ausser dem Punkt) in Gruppen vorkommen.

Eine gültige Zeichenkette wäre zum Beispiel TT.PPP oder PPPP.PPPP oder TT.ppp oder B.A.TT.PPP

Mit meinem Pattern werden aber auch Tbappppppp.PPP.PPP als gültig erkannt.

Ich hoffe jemand hat eine Idee.
Die Online Regex-Generatoren helfen mir da leider nicht weiter :(
05.08.2011
Christian M. Müller 251 1 7
4 Antworten
2
Innerhalb [character-sets] muss man nicht alles bzw. anders escapen. Der Punkt muss z.B. nicht gesondert behandelt werden (macht aber auch nichts aus, wenn man es tut - ist nur ein wenig unübersichtlicher).

Rein nach Deiner Anforderung würde ich z.B. sowas hier verwenden

^([BbAaTtPp])\1*\b(?:\.([BbAaTtPp])\2*\b)*$

Da muss man zwar das character-set 2x angeben, aber das ist in dem Fall nicht so schlimm. Falls doch, geht (zumindest in .net und JavaScript) auch

^(?!\.)(?:\.?\b([BbAaTtPp])\1*\b)*$

Der Unterschied zu deinem Pattern ist, dass hier eine "backreference" verwendet wird (eigentlich etwas schrecklich unreguläres *g*).
\1 verweist auf den Treffer der ersten Klammer (die nicht mit ?: oder ?! versehen ist), \2 entsprechend auf den Wert der 2. Klammer. Dabei wird nicht nochmal das character-set abgefragt, sondern der damit ausgewählte Wert.
Mit
([ab])\1
wird also z.B. "aa" und "bb" ausgewählt, nicht aber "ab"

Edits: typo
05.08.2011
WolfgangKluge 1,0k 2 7
JA, das ist es :)
Vielen Dank!
Christian M. Müller 05.08.2011
1
Hallo,

das carpet ^ steht immer für den Zeilenanfang. Innerhalb der anderen eckigen Klammern ist das also falsch. Den Punkt zu Escape ist richtig, da er im Regex ein Sonderzeichen ist.

Jetzt musst Du Deinen Ausdruck so umbauen, dass eines der angegeben Zeichen einmal oder öfter vorkommen darf und dann der Punkt nur, wenn danach noch ein Zeichen einmal oder öfter kommt.

^[BbAaTtPp]*(\.[BbAaTtPp]*)*$

So müssten wir der Sache schon näher kommen.
05.08.2011
LutzJ 1,3k 1 8
Danke erstmal für die Antwort.
Ich hab das mal ausprobiert, und nun wird ein Punkt am Anfang auch gültig erkannt... (ich teste die auf http://gskinner.com/RegExr)
Christian M. Müller 05.08.2011
1
^ innerhalb [sets] steht für "nicht", nur ausserhalb für Text- bzw. Zeilenanfang (je nachdem, ob die Option RegexOptions.Miltiline (so zumindest in .net) gesetzt ist, oder nicht)
WolfgangKluge 05.08.2011
0
Hallo,

Wie wäre es mit etwas in der Richtung:

^(([B]+|[b]+|[A]+|[a]+|[T]+|[t]+|[P]+|[p]+)(\.|$))*
05.08.2011
Tachyon 690 1 7
Tachyon 690 1 7
Danke für die Antwort, aber das funktioniert leider auch nicht...
Christian M. Müller 05.08.2011
0
Es geht bestimmt eleganter, aber damit sollte es zumindest funktionieren:

^(([B]+|[b]+|[A]+|[a]+|[T]+|[t]+|[P]+|[p]+)\.)+([B]+|[b]+|[A]+|[a]+|[T]+|[t]+|[P]+|[p]+)$
05.08.2011
Tachyon 690 1 7

Stelle deine Regex-Frage jetzt!