Erfassen der ersten Nummer im Text mit Regex in Javascript

8

Kontext

Ich habe einige CSS, um Übergänge zu machen:

%Vor%

Ich versuche, den maximalen Wert in dieser Liste zu finden, was einfach mit einem regulären Ausdruck zu tun ist.

%Vor%

Mein Problem ist, dass wenn ich den CSS-Wert

bekomme %Vor%

es kommt zurück als

%Vor%

Jetzt bekommt meine Regex auch die Verzögerungswerte (" 0 "). Wenn ich bedenke, dass ich versuche, das Maximum zu finden, ist das auch in Ordnung, aber ich bin ein Purist im Herzen, und ich möchte die Matches auf die Übergangszeiten beschränken.

Meine zerbrochene Lösung

Die Regex, die ich zusammengebraut habe, ist

%Vor%

Die Begründung:

%Vor%

Wenn ich renne

%Vor%

Die Ergebnisse für jedes m sind:

%Vor%

jsfiddle Beispiel

Ich dachte, dass die Idee einer nicht einfangenden Gruppe darin besteht, dass sie den Charakteren entspricht, sie aber ignoriert, wenn Sie versuchen, auf die Gruppen zuzugreifen.

Ich habe die Vermutung, dass ich eher Matches als Gruppen betrachte, aber ich habe nicht herausgefunden, wie man die Gruppen stattdessen bekommt.

Hilfe?

UPDATE 1

Pro Kommentar habe ich

aktualisiert %Vor%

und probierte es mit RegExp.exec() aus (was ich bereits zuvor versucht hatte, obwohl es nicht funktionierte, bis ich r aktualisiert habe). Das Ergebnis ist

%Vor%

m[1] erfasst die erste Zahl, ignoriert jedoch die folgenden.

Ich entdeckte auch, dass das Problem, das ich mit t.match(r) hatte, das /g -Flag war. Wenn Sie es entfernen, erhalten Sie das gleiche Ergebnis wie r.exec(t) .

Abgesehen von der Aufteilung von t auf ',' und dem Ausführen der Regex für jeden Term, gibt es eine Möglichkeit, dies in einer einzigen Regex zu tun?

UPDATE 2

@Esteban Felix alternative Antwort ist eindeutig die beste Option.

%Vor%

TL; DR: Verwenden Sie das obige für diesen Fall, aber hier ist eine Erklärung, warum Sie vielleicht in anderen Fällen nicht sollten.

Die einzige Änderung, die ich in Erwägung ziehen würde, wäre das Anhängen von + an das Ende von [^\d\.,] , um die Anzahl der Ersetzungen zu verringern und die Leistung um einen nicht mehr vorstellbaren Betrag in häufigeren Strings zu verbessern (nicht den .css('transition-duration') Fall, wie ich in einer Sekunde erklären werde.

Der Grund dafür, dass die Leistung verbessert werden kann, besteht darin, dass die Zeichenfolgen in Javascript unveränderlich sind. Daher kostet das Erstellen einer neuen Zeichenfolge für jedes entfernte Zeichen Zeit. In meinem Fall sind das nur die 's und s ' s. Mit einer Folge von

%Vor%

die Leerzeichen und die s sind nie nebeneinander, so dass das Ergebnis tatsächlich eine Verschlechterung der Performance wäre, da die Regex-Engine nun jedes Mal das folgende Zeichen überprüfen muss, wenn ein zu entfernendes Zeichen gefunden wird. Bei häufigeren Zeichenfolgen, bei denen Sie viele fortlaufende Zeichen entfernen, kann das Hinzufügen von + jedoch die Leistung verbessern. Der einzige Grund, warum dies nicht der Fall ist, ist, dass die Implementierung von String.replace() intelligent ist und ein Zeichenarray hinter den Kulissen verwendet und am Ende der Funktion nur Platz für eine neue Zeichenfolge reserviert. Dieser Aspekt ist Browser-abhängig, aber ich denke, das ist der übliche Fall für moderne Browser.

Es ist auch wichtig zu wissen, dass es wichtig ist, ein + und nicht ein * zu verwenden, da letzteres jeder Position zwischen den Zeichen entspricht und die übereinstimmende leere Zeichenfolge durch die angegebene leere Zeichenfolge ersetzt. Ich weiß nicht, ob die JavaScript-Engine eine Menge neuer, identischer Strings erzeugen würde oder nicht, aber es kann die Performance sicherlich nicht verbessern.

Wenn Sie wirklich auf diese häufig vernachlässigbare Leistungsschwankung achten, sollten Sie einige Benchmarks lesen. Der einzige mögliche Weg, auf dem Sie überhaupt einen Unterschied sehen, ist

  1. Sie führen den Code auf einem Compaq Presario 286 MMX mit 64 MB RAM (d. h. meinem ersten Computer von 1997) oder
  2. aus
  3. Sie führen diesen Regex-Ersatz viele tausend Male in einer inneren Schleife für Strings durch, wobei die meisten zu entfernenden Zeichen in langen, ununterbrochenen Läufen in
  4. sind
  5. Internet Explorer 1.5

Die Änderung an der ausgewählten Antwort könnte also tatsächlich die Leistung in Abhängigkeit von Ihrem Browser und der Art der Strings, gegen die Sie sie ausführen, reduzieren. Aber wie ich bereits sagte, bin ich ein Purist und liebe Verallgemeinerung und Optimierung also meine Erklärung.

    
dfoverdx 27.10.2014, 19:56
quelle

1 Antwort

2

Sie möchten RegExp.exec anstelle von RegExp.match verwenden.

Wie verwendet man RegExp.exec (aus MDN ) ):

  

Wenn Ihr regulärer Ausdruck das Flag "g" verwendet, können Sie die exec-Methode mehrmals verwenden, um aufeinanderfolgende Übereinstimmungen in derselben Zeichenfolge zu finden. Wenn Sie dies tun, beginnt die Suche an der Teilzeichenfolge von str, die durch die lastIndex-Eigenschaft des regulären Ausdrucks angegeben wird (test () wird auch die lastIndex-Eigenschaft weiterleiten).

Ein Beispiel mit Ihrem Code:

%Vor%

Außerdem gibt es ein kleines Problem mit Ihrer Regex, das dazu führt, dass die Zahl nach der Dezimalstelle nicht erfasst wird. Der aktualisierte Regex:

/(?:[^\d\.]*)(\d*\.?\d+)(?:s[^,]*)/g

Alternative

Sie können auch, statt auf transition zu schauen, auf die Eigenschaft schauen, die Sie eigentlich interessieren, nämlich transition-duration .

%Vor%

Dann können Sie das Array direkt durchlaufen.

    
Esteban Felix 27.10.2014, 20:10
quelle

Tags und Links