Wechsel- oder Zeichenklasse für die Übereinstimmung einzelner Zeichen verwenden?

8

(Hinweis: Titel scheint nicht klar zu sein - wenn jemand das umformulieren kann, bin ich dafür!)

Angesichts dieser Regex: (.*_e\.txt) , die mit einigen Dateinamen übereinstimmt, muss ich zusätzlich zum e einige andere Suffixe mit einem einzelnen Zeichen hinzufügen. Soll ich eine Charakterklasse wählen oder soll ich dafür eine Alternative verwenden? (Oder spielt es wirklich eine Rolle?)

Das heißt, welches der folgenden zwei scheint "besser" und warum:

a) (.*(e|f|x)\.txt) oder

b) (.*[efx]\.txt)

    
Martin Ba 18.01.2011, 13:28
quelle

3 Antworten

16

Verwenden Sie [efx] - genau dafür sind Zeichenklassen gedacht: um eines der enthaltenen Zeichen zu finden. Daher ist es auch die am besten lesbare und kürzeste Lösung.

Ich weiß nicht, ob es schneller ist, aber ich wäre sehr überrascht, wenn es nicht wäre. Es wird definitiv nicht langsamer sein.

Meine Argumentation (ohne jemals eine Regex-Engine geschrieben zu haben, das ist reine Vermutung):

Das Regex-Token [abc] wird in einem einzigen Schritt der Regex-Engine angewendet: "Ist das nächste Zeichen eins von a , b oder c ?"

(a|b|c) sagt der Regex-Engine jedoch

  • merken Sie sich gegebenenfalls die aktuelle Position in der Zeichenfolge für das Zurückverfolgen
  • Überprüfen Sie, ob a übereinstimmt. Wenn ja, Erfolg. Wenn nicht:
  • Überprüfen Sie, ob b gefunden werden kann. Wenn ja, Erfolg. Wenn nicht:
  • Überprüfen Sie, ob c gefunden werden kann. Wenn ja, Erfolg. Wenn nicht:
  • gib auf.
Tim Pietzcker 18.01.2011, 13:30
quelle
11

Hier ist ein Benchmark:

aktualisiert nach tchrist Kommentar, der Unterschied ist signifikanter

%Vor%

Ergebnis:

%Vor%     
Toto 18.01.2011 13:52
quelle
1

Mit einem einzelnen Zeichen wird es so einen minimalen Unterschied geben, dass es egal ist. (es sei denn, du machst viele Operationen)

Aus Gründen der Lesbarkeit (und einer leichten Leistungssteigerung) sollten Sie jedoch die Zeichenklassenmethode verwenden.

Für ein bisschen mehr Informationen - das Öffnen einer runden Klammer ( bewirkt, dass Perl mit dem Zurückverfolgen der aktuellen Position beginnt, was Sie für Ihre Regex wirklich nicht brauchen, da Sie keine weiteren Übereinstimmungen haben, gegen die Sie antreten können. Eine Zeichenklasse wird dies nicht tun.

    
Mez 18.01.2011 13:51
quelle

Tags und Links