it-swarm.com.de

Regex genau n OR m mal

Betrachten Sie den folgenden regulären Ausdruck, wobei X any regex ist.

X{n}|X{m}

Dieser reguläre Ausdruck würde auf X prüfen, die genau n oder m-Zeiten auftreten.

Gibt es einen Regex-Quantifizierer, der auf ein Vorkommen X genau n oder m mal testen kann?

74
Vulcan

Es gibt keinen einzelnen Quantifizierer, der "genau m oder n mal" bedeutet. Die Art, wie Sie es tun, ist in Ordnung.

Eine Alternative ist:

X{m}(X{k})?

dabei ist m < n und k der Wert von n-m

68
Mark Byers

Hier ist die vollständige Liste der Quantifizierer (Ref. http://www.regular-expressions.info/reference.html ):

  • ?, ?? - 0 oder 1 Vorkommen (?? ist faul, ? ist gierig)
  • *, *? - beliebig viele Vorkommen
  • +, +? - mindestens ein Vorkommen
  • {n} - genau n Vorkommen
  • {n,m} - n bis m-Vorkommen, einschließlich
  • {n,m}? - n zu m geschieht, faul
  • {n,}, {n,}? - mindestens n Vorkommen

Um "genau N oder M" zu erhalten, müssen Sie den quantifizierten Regex zweimal schreiben, es sei denn, m, n sind speziell:

  • X{n,m} wenn m = n+1
  • (?:X{n}){1,2} wenn m = 2n
  • ...
42
John Dvorak

Nein, es gibt keinen solchen Quantifizierer. Aber ich würde es in /X{m}(X{m-n})?/ umstrukturieren, um Probleme beim Backtracking zu vermeiden.

18
Bergi

TLDR; (?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

Sieht aus wie Sie wollen "x n mal" oder "x m mal", ich denke, eine wörtliche Übersetzung in regex wäre (x{n}|x{m}).Like dies https://regex101.com/r/vH7yL5/1

in einem Fall, in dem Sie eine Sequenz von mehr als m "x" s haben können (unter der Annahme von m> n), können Sie Folgendes hinzufügen: "no" "x" "und" ", gefolgt von" x ", wobei" [^x](x{n}|x{m})[^x] "übersetzt wird würde davon ausgehen, dass hinter und hinter dir immer ein "x" s steht. Wie Sie hier sehen können: https://regex101.com/r/bB2vH2/1

sie können es in (?:[^x]|^)(x{n}|x{m})(?:[^x]|$) ändern und in "nach keinem 'x' oder folgenden Zeilenanfang" und "gefolgt von keinem 'x' oder gefolgt von einem Zeilenende" übersetzen. Trotzdem passt es nicht zu zwei Sequenzen, bei denen nur ein Zeichen dazwischen ist (da für das erste Match ein Zeichen nach und das zweite Zeichen zuvor benötigt wird), wie Sie hier sehen können: https://regex101.com/ r/oC5oJ4/1

Um die Übereinstimmung eines Zeichens mit einem Zeichen zu erreichen, können Sie einen positiven Blick nach vorne (? =) Auf "kein" x "nach" oder einen positiven Blick nach hinten (? <=) Auf "kein" x "vor" hinzufügen. wie folgt: https://regex101.com/r/mC4uX3/1

(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

Auf diese Weise werden Sie nur die exakte Anzahl von 'x' finden, die Sie möchten.

2
Enhardened

Wenn man sich die Antwort von Enhardened ansieht, sagen sie, dass ihr vorletzter Ausdruck nicht Sequenzen mit nur einem Zeichen dazwischen entspricht. Es gibt eine einfache Möglichkeit, dies zu beheben, ohne vorausschauend/rückwärts zu arbeiten. Das Start-/Endzeichen wird durch das Begrenzungszeichen ersetzt. Auf diese Weise können Sie Word-Grenzen abgleichen, die Anfang/Ende enthalten. Daher sollte der entsprechende Ausdruck lauten:

(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)

Wie Sie hier sehen können: https://regex101.com/r/oC5oJ4/2 .

0
rozza2058

Sehr alter Beitrag, aber ich möchte gerne etwas beitragen, das mir helfen könnte ... Ich habe es genau so ausprobiert, wie es in der Frage angegeben ist, und es funktioniert, aber es gibt einen Haken: Angelegenheiten. Bedenken Sie:

#[a-f0-9]{6}|#[a-f0-9]{3}

Dadurch werden alle Vorkommen von Hex-Farbcodes gefunden (sie sind entweder 3- oder 6-stellig). Aber wenn ich es so umdrehe 

#[a-f0-9]{3}|#[a-f0-9]{6}

es werden nur die 3 Ziffern oder die ersten 3 Ziffern der 6 Ziffern gefunden. Das macht Sinn, und ein Regex-Profi könnte dies sofort erkennen, aber für viele ist dies möglicherweise ein besonderes Verhalten. Es gibt einige erweiterte Regex-Funktionen, die diese Falle unabhängig von der Reihenfolge vermeiden könnten, aber nicht jeder ist in Regex-Mustern verkniffen.

0
DanDan