Können Sie nur einen Teil eines Regex machen, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird?

100

Ich habe viele Beispiele dafür gesehen, wie ein ganzer regulärer Ausdruck ohne Berücksichtigung der Groß- und Kleinschreibung verwendet wird. Ich wundere mich, dass nur ein Teil des Ausdrucks die Groß- und Kleinschreibung nicht berücksichtigt.

Nehmen wir zum Beispiel an, ich habe eine Zeichenfolge wie diese:

fooFOOfOoFoOBARBARbarbarbAr

Was ist, wenn ich alle Vorkommen von "foo" unabhängig von der Groß- und Kleinschreibung abgleichen möchte, aber nur die Großbuchstaben "BAR" abgleichen möchte?

Die ideale Lösung wäre etwas, das über Regex-Geschmacksrichtungen hinweg funktioniert, aber ich bin auch daran interessiert, sprachspezifische zu hören (Danke Espo ).

Bearbeiten

Der von Espo bereitgestellte Link war sehr hilfreich. Es gibt dort ein gutes Beispiel für das Ein- und Ausschalten von Modifikatoren innerhalb des Ausdrucks.

Für mein erfundenes Beispiel kann ich so etwas tun:

(?i)foo*(?-i)|BAR

Dies macht das Match nur für den foo-Teil des Matchs unabhängig von Groß- und Kleinschreibung.

Das schien in den meisten Regex-Implementierungen zu funktionieren, außer in Javascript, Python und einigen anderen (wie Espo erwähnte).

Die großen, über die ich mich gewundert habe (Perl, PHP, .NET), unterstützen alle Änderungen im Inline-Modus.

Mark Biek
quelle
Diese Frage wurde zu den häufig gestellten Fragen zum Stapelüberlauf für reguläre Ausdrücke unter "Modifikatoren" hinzugefügt .
Aliteralmind

Antworten:

88

Mit Perl können Sie einen Teil Ihres regulären Ausdrucks unabhängig von Groß- und Kleinschreibung machen, indem Sie den Mustermodifikator (? I :) verwenden.

Mit modernen Regex-Aromen können Sie Modifikatoren nur auf einen Teil des regulären Ausdrucks anwenden. Wenn Sie den Modifikator (? Ism) in die Mitte des regulären Ausdrucks einfügen, gilt der Modifikator nur für den Teil des regulären Ausdrucks rechts vom Modifikator. Sie können Modi ausschalten, indem Sie ihnen ein Minuszeichen voranstellen. Alle Modi nach dem Minuszeichen werden ausgeschaltet. ZB (? I-sm) aktiviert die Groß- und Kleinschreibung und deaktiviert sowohl den Einzeilen- als auch den Mehrzeilenmodus.

Nicht alle Regex-Aromen unterstützen dies. JavaScript und Python wenden alle Modusmodifikatoren auf den gesamten regulären Ausdruck an. Sie unterstützen die (? -Ismx) -Syntax nicht, da das Deaktivieren einer Option sinnlos ist, wenn Modusmodifikatoren auf die gesamten regulären Ausdrücke angewendet werden. Alle Optionen sind standardmäßig deaktiviert.

Sie können schnell testen, wie die Regex-Variante, die Sie verwenden, Modifikatoren für den Handle-Modus verwendet. Der Regex (? I) te (? - i) st sollte mit test und TEst übereinstimmen, nicht jedoch mit teST oder TEST.

Quelle

Espo
quelle
6

Welche Sprache benutzt du? Ein Standardweg, dies zu tun, wäre so etwas wie / ([Ff] [Oo] {2} | BAR) / mit aktivierter Groß- und Kleinschreibung, aber in Java gibt es beispielsweise einen Modifikator für die Groß- und Kleinschreibung (? I), der alles macht Zeichen rechts davon unterscheiden zwischen Groß- und Kleinschreibung und (? -i) was die Empfindlichkeit erzwingt. Ein Beispiel für diesen Java-Regex-Modifikator finden Sie hier .

Akdom
quelle
+1 Warum sollte man die Groß- und Kleinschreibung nicht
berücksichtigen,
11
@NonaUrbiz: Weil der Ausdruck (?i)foobarbesser lesbar ist als[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos
1
Und weil es wachsen kann Art und Weise viel mehr behaarte und komplex.
Chop
6

Leider ist die Syntax für Matching ohne Berücksichtigung der Groß- und Kleinschreibung nicht üblich. In .NET können Sie das RegexOptions.IgnoreCase-Flag oder den Modifikator ? I verwenden

aku
quelle
4

Du könntest benutzen

(?:F|f)(?:O|o)(?:O|o)

Das?: In den Klammern in .Net bedeutet, dass es nicht erfasst wird und nur zum Gruppieren der Begriffe des | verwendet wird (oder) Aussage.

Kibbee
quelle
26
Ist "[fF] [oO] [oO]" nicht die bessere Alternative? Für das vorliegende Beispiel könnten Sie sogar bis zu "[fF] [oO] \ {2}" gehen ;-)
Tomalak
4

Es ist wahr, dass man sich auf Inline-Modifikatoren verlassen kann, wie unter Ein- und Ausschalten von Modi nur für einen Teil des regulären Ausdrucks beschrieben :

Die Regex (?i)te(?-i)stsollte mit Test und TEst, aber nicht teSToder übereinstimmen TEST.

Eine etwas besser unterstützte Funktion ist jedoch eine (?i:...)Inline-Modifikatorgruppe (siehe Modifikatorbereiche ). Die Syntax lautet (?i:dann das Muster, das Sie cas-unempfindlich machen möchten, und dann a ).

(?i:foo)|BAR

Das Umgekehrte : Wenn Ihr Muster mit Groß- und Kleinschreibung Option kompiliert wird , und Sie müssen einen Teil eines regex Groß- und Kleinschreibung machen, fügen Sie -nach ?: (?-i:...).

Beispielverwendungen in verschiedenen Sprachen (Umschließen der Übereinstimmungen mit spitzen Klammern):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( Demo )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( Demo ) (Hinweis Python reunterstützt Inline-Modifikatorgruppen seit Python 3.6)
  • /. /. - Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>")( Demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")( Demo )
  • - $s =~ s/(?i:foo)|BAR/<$&>/g( Demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')( Demo )
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)( Demo )
  • - - "fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (verwendet RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( Demo )

Wird in nicht unterstützt , , , std::regex, , .

Wiktor Stribiżew
quelle