Also das Problem ist bei mir das ich den regulären Ausdruck bei zwei Zeichenketten anwenden will. Aber wie bei dem Beispielcode zu sehen ist, kommt bei dem zweiten test nur false. Bei der Funktion exec ist ähnlich :<
test() ruft intern exec() auf.
Das ist eine Eigenart des RegExp-Objektes, dass dieses unter gewissen Umständen nach einmaliger Anwendung „verbraucht“ ist.
Das kann man so nicht sagen.
(Genauer kann ich dir das auch nicht erklären, da müssen wir auf Mathias oder jemand anderen warten.)
Wir haben es kurzerhand in SELFHTML reingeschrieben, damit ich nicht immer anwesend sein muss. ;)
http://de.selfhtml.org/javascript/objekte/regexp.htm#exec
Siehe zweites Beispiel
Wenn man mehrfach exec() bei einem regulären Ausdruck mit dem global-Modifier aufruft, dann kann man damit alle Treffer durchlaufen. Der Vorteil gegenüber String.prototype.match() ist, dass man komplexen Ausdrücken mit Klammern für Teiltreffer Zugriff auf die Teiltreffer jedes der Treffer hat.
Dieses Durchlaufen funktioniert so: Beim exec() speichert JS die Position, an der der erste Treffer gefunden hat, und sucht beim nächsten exec()-Aufruf erst ab dieser Position weiter. Die Position wird in der Eigenschaft lastIndex gespeichert (vgl. EC5).
Erst wenn die Suche man am Stringende angelangt ist, wird lastIndex auf 0 zurückgesetzt:
r = /\d/g
/\d/g
r.exec("a1b2d3e4")
["1"]
r.lastIndex
2
r.exec("a1b2d3e4")
["2"]
r.lastIndex
4
r.exec("a1b2d3e4")
["3"]
r.lastIndex
6
r.exec("a1b2d3e4")
["4"]
r.lastIndex
8
r.exec("a1b2d3e4")
null
// Am Ende angelangt, daher wurde lastIndex zurückgesetzt:
r.lastIndex
0
r.exec("a1b2d3e4")
["1"]
// Jetzt gehts wieder von vorne los
r.lastIndex
2
usw. ad infinitum
Sinn macht das natürlich nur, wenn man exec() immer wieder auf *denselben* String anwendet, bis kein Treffer mehr gefunden ist, weil die Suche am Stringende angelangt ist (wie im obigen Beispiel). Wenn man den global-Flag setzt und exec() ständig auf unterschiedliche Strings anwendet, kommt Quatsch heraus:
r.exec("20")
["20"]
r.lastIndex
2
r.exec("40")
null
r.lastIndex
0
// Hier wurde zurückgesetzt, also wird beim dritten exec() wieder von vorne gesucht:
r.exec("20")
["20"]
r.lastIndex
2
r.exec("40")
null
r.lastIndex
0
usw.
Diese RegExp kann man also durchaus mehrfach verwenden und auf unterschiedliche Strings, aber sie sucht eben nicht immer von vorne, sondern merkt sich die Position von der Anwendung auf den jeweils letzten String.
So jetzt mein Frage kann man einen regulären Ausdruck auf zwei Zeichenketten anwenden und wie?
Lass einfach den global-Flag weg.
r = /\d\d/
/\d\d/
r.test("20")
true
r.test("40")
true
Funktioniert wie erwartet.
Du kannst die compile-Methode nutzen - die ist sowieso empfehlenswert, weil sie den Ausdruck in ein Format „kompiliert“, mit dem er bei mehrfacher Ausführung m.W. schneller ausgewertet werden kann.
Das ist meines Wissens nicht nötig. Die neueren JS-Engines optimieren selbstständig. compile() war m.W. auch nie standardisiert, sondern eine Netscape-3-Spezialität. Netscape JavaScript 1.5 (Netscape 4) hat compile() schon als deprecated erklärt. (Ich find überhaupt nichts neueres dazu.)
Mathias