greedy: Regulärer Ausdruck im Javascript

Hallo !

ich habe folgende zeichenkette, aus der ich (alle) durch doppelte eckige Klammer eingeschlossene Zeichenketten extrahieren möchte.

'bla bla [[for(var i=0; i<arr.length; i++) { alert(arr[i]); }]]; bla bla --- [[xxxx]]'

Da es positive lookbehind im Javascript nicht gibt (oder?), gestaltet sich die Suche entsprechend schwierig.

Ich mache es mit folgender regular expression:

\[\[[^\[\]]+\]\]

d.h. ich suche nach aufeinanderfolgenden Klammern, die folgenden Ausdruck umschliessen:

[^\[\]]+

Damit will ich festlegen, dass das RegExp-Objekt nur bis zum nächsten abschliessenden String \]\] sucht und die gefundene Zeichenkette einfängt, die ich anschliessend mit der anonymen Funktion bearbeiten kann (siehe unten).

Man könnte sich an dieser Stelle fragen, wieso der Ausdruck so kompliziert ist, es wäre doch ausreichend folgendes zu schreiben:

\[\[.+\]\]

allerdings würde dann RegExp die gesamte Zeichenkette bis zum letzten "]]" im String einfangen (Stichwort greedy). Daher möchte ich Zeichen, die nicht enthalten sein dürfen, festlegen. Das wäre mit

[^\[\]]+

getan. Dieser Teilausdruck ist eben falsch, da er nur eine Gruppe an Zeichen definiert, die nicht enthalten sein dürfen. Wenn mindestens 1 Zeichen davon in der übergebenen Zeichenkette enthalten ist, wird natürlich nichts gefunden, da an der Stelle mit <pre>arr[i]</pre> eckige Klammern vorhanden sind. Wie kann ich den regulären Ausdruck so anpassen, dass ich eine exakte Zeichenkette definiere, die nicht vorkommen darf (nicht nur eine Gruppe wie oben).

var test = 'bla bla [[for(var i=0; i<arr.length; i++) { alert(arr[i]); }]]; bla bla --- [[xxxx]]';
testPattern = new RegExp('\[\[[^\[\]]+\]\]', 'g');
test = test.replace( testPattern, function($0,$1) {

var test = "";
 for(var i=0; i<arguments.length; i++) {
  test += "argument " + i + ":" + arguments[i] + "\n";
 }
 alert( test);

return($1 != -1) ? "ausdruck gefunden" : $2;

});
alert( test );

Hinweis: im obigen Script wird nur [[xxxx]] gefunden und ersetzt, nicht [for ...]].

Danke für eure Hilfe.
greedy

  1. gudn tach!

    ich habe folgende zeichenkette, aus der ich (alle) durch doppelte eckige Klammer eingeschlossene Zeichenketten extrahieren möchte.

    'bla bla [[for(var i=0; i<arr.length; i++) { alert(arr[i]); }]]; bla bla --- [[xxxx]]'

    Da es positive lookbehind im Javascript nicht gibt (oder?), [...]

    ich glaube, die meisten browser koennen das, aber ich weiss es nicht.

    loesungsvorschlag (ungetestet):
      str.match(/[[.*?]]/g);

    .*? sucht non-greedy.

    falls die eckigen klammern wegsollen, kannst du sie entweder nachtraeglich wegschneiden, oder mal
      str.match(/(?:[[).*?(?:]])/g);
    probieren. ich weiss aber nicht, ob js non-capturing patterns a la (?:) kennt.

    prost
    seth

    1. hi !
      thx, hat geklappt mit:

      str.match(/[[.*?]]/g);

      greedy