Calocybe: REGULÄRE AUSDRÜCKE - Ich werd' noch zu Profi ;-)

Beitrag lesen

Moin!

der reguläre Ausdruck, der auch funktioniert sieht so aus:
   var reg = new RegExp("([ \t\v\n\r\f]//.*)","g")
NICHT funktionieren tut dagegen dies:
   var reg = new RegExp("(\s//.*)","g")
obwohl doch \s = [ \t\v\n\r\f] ist oder?

Versuch mal, ob der zweite Ausdruck eine Zeile findet, die mit "s//" beginnt. Falls ja, dann gilt folgende Erklaerung:

Wenn Du in JS einen String "abc" hinschreibst, dann werden darin enthaltene sog. Backslash-Escape-Sequenzen in deren Bedeutung umgewandelt. D.h., Wenn Du "a\tb" schreibst, dann wirst Du nicht einen 4 Zeichen langen String mit den Zeichen a, , t, b erhalten, sondern einen mit den 3 Zeichen a, <TAB character (ASCII 9)>, b. Schreibst Du einen \ vor ein Zeichen, welches *keine* solche Sonderbedeutung wie z.B. t,v,n,r,f hat, dann ist das Ergebnis der -Esc-Sequenz einfach das Zeichen selbst, ohne den Backslash. "a\sb" ist daher dasselbe wie "asb". Und oben schreibst Du ja gerade \s in einem String. Erst spaeter wird dann dieser String zu einem RegExp weiterverarbeitet, aber dann ist der \ schon laengst Geschichte. Der RegExp constructor ist aber darauf angewiesen, alle diese Zeichen zu bekommen, denn erst *er* wird dem \s seine Sonderbedeutung in regulaeren Ausdruecken geben.

Du hast im wesentlichen zwei Moeglichkeiten.
Entweder Du schreibst gleich ein RegExp-Literal in den Source Code:
  var reg = /(\s//.*)/g
Das ist praktisch gleichbedeutend mit dem von oben, nur dass das \s jetzt *nicht* im Voraus zu einem einfachen s kollabiert wird, denn dies hier ist ein RegExp-Literal, kein String-Literal, da sind die Regeln anders. Dafuer hast Du jetzt das "Leaning Toothpick Syndrome" (LTS - gemeint sind die /). Du musst die / maskieren, da ein einfacher, unmaskierter / das Literal vorzeitig beenden wuerde. Das ist so aehnlich wie wenn Du in einem String-Literal ein " aufnehmen willst und deswegn "ab"cd" schreibst.

Oder Du maskierst halt den den \ selber auch noch:
  var reg = new RegExp("(\s//.*)", "g")
sodass zunaechst die Sequenz \ zu einem \ kollabiert wird, und dann vom RegExp constructor das verbliebene \s entsprechend interpretiert wird. Damit umgehst Du das LTS von oben, aber musst dafuer in mehreren Ebenen mitdenken, denn wann bedeuted welche -Sequenz was. Aber Du dafuer Deine RegExpe einfach dynamisch zur Laufzeit zusammensetzen, waehrend ja ein Literal zur Entwurfszeit festgelegt wird (dafuer sind Literale ja da). [1]

Dir ist jetzt natuerlich klar, dass der String "([ \t\v\n\r\f]//.*)" diese Whitespace-Zeichen TAB, LF usw. direkt enthaelt, wenn er zum RegExp constructor gegeben wird. Das st eigentlich nicht so schoen. Man schreibt ja auch nicht
  / <TAB>
.../
direkt in den Quelltext (darf man gar nicht).

[1] So ein RegExp-Literal hat noch die Eigenschaft, dass wenn man es z.B. in einer Schleife verwendet, immer dieselbe Instanz des daraus erzeugten RegExp-Objektes verwendet wird, waehrend new RegExp jedesmal ein neues Objekt erzeugt. Das kann gewisse Implikationen fuer das Programm haben, die ich aber an dieser Stelle auch nicht ueberblicke.

HTH && So long

--
When a man and a woman marry they become one.
The trouble starts when they try to decide which one.

[calokey: js javascript RegExp string literal backslash escape sequence]