Pouvez-vous faire juste une partie d'une regex insensible à la casse?

101

J'ai vu de nombreux exemples permettant de rendre toute une expression régulière insensible à la casse. Ce que je me demande, c'est qu'une partie de l'expression ne soit pas sensible à la casse.

Par exemple, disons que j'ai une chaîne comme celle-ci:

fooFOOfOoFoOBARBARbarbarbAr

Que faire si je veux faire correspondre toutes les occurrences de "foo" quelle que soit la casse mais que je veux seulement faire correspondre les "BAR" majuscules?

La solution idéale serait quelque chose qui fonctionne avec les saveurs de regex, mais je suis également intéressé à entendre celles spécifiques à une langue (merci Espo )

Éditer

Le lien fourni par Espo a été très utile. Il y a un bon exemple d'activation et de désactivation des modificateurs dans l'expression.

Pour mon exemple artificiel, je peux faire quelque chose comme ceci:

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

ce qui rend la correspondance insensible à la casse uniquement pour la partie toto de la correspondance.

Cela semblait fonctionner dans la plupart des implémentations de regex, sauf Javascript, Python et quelques autres (comme Espo l'a mentionné).

Les grands sur lesquels je m'interrogeais (Perl, PHP, .NET) supportent tous les changements de mode en ligne.

Mark Biek
la source
Cette question a été ajoutée à la FAQ sur les expressions régulières Stack Overflow , sous "Modificateurs".
aliteralmind

Réponses:

88

Perl vous permet de rendre une partie de votre expression régulière insensible à la casse en utilisant le modificateur de motif (? I :).

Les saveurs de regex modernes vous permettent d'appliquer des modificateurs à une partie seulement de l'expression régulière. Si vous insérez le modificateur (? Ism) au milieu de l'expression régulière, le modificateur s'applique uniquement à la partie de l'expression régulière à droite du modificateur. Vous pouvez désactiver les modes en les faisant précéder d'un signe moins. Tous les modes après le signe moins seront désactivés. Par exemple, (? I-sm) active l'insensibilité à la casse et désactive à la fois le mode une ligne et le mode multiligne.

Toutes les versions de regex ne le supportent pas. JavaScript et Python appliquent tous les modificateurs de mode à l'ensemble de l'expression régulière. Ils ne prennent pas en charge la syntaxe (? -Ismx), car désactiver une option est inutile lorsque les modificateurs de mode s'appliquent à l'ensemble des expressions régulières. Toutes les options sont désactivées par défaut.

Vous pouvez rapidement tester la façon dont la saveur de regex que vous utilisez gère les modificateurs de mode. La regex (? I) te (? - i) st doit correspondre à test et TEst, mais pas à teST ou TEST.

La source

Espo
la source
6

Quelle langue utilisez-vous? Une manière standard de faire cela serait quelque chose comme / ([Ff] [Oo] {2} | BAR) / avec la sensibilité à la casse activée, mais en Java, par exemple, il existe un modificateur de sensibilité à la casse (? I) qui rend tout caractères à droite de celui-ci insensible à la casse et (? -i) qui force la sensibilité. Un exemple de ce modificateur d'expression régulière Java peut être trouvé ici .

akdom
la source
+1 Pourquoi prendre la peine de le rendre insensible à la casse quand vous pouvez faire correspondre les deux cas
Nona Urbiz
11
@NonaUrbiz: Parce que l'expression (?i)foobarest plus lisible que[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos
1
Et parce qu'il peut se développer façon beaucoup plus poilu et complexe.
Chop le
6

Malheureusement, la syntaxe pour la correspondance insensible à la casse n'est pas courante. Dans .NET, vous pouvez utiliser l'indicateur RegexOptions.IgnoreCase ou le modificateur ? I

aku
la source
4

Vous pourriez utiliser

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

Le?: Entre parenthèses dans .Net signifie qu'il n'est pas capturant, et juste utilisé pour regrouper les termes du | (ou) déclaration.

Kibbee
la source
26
"[FF] [oO] [oO]" n'est-il pas la meilleure alternative? Pour l'exemple à portée de main, vous pourriez même aller aussi loin que "[fF] [oO] \ {2}" ;-)
Tomalak
4

Il est vrai que l'on peut s'appuyer sur des modificateurs en ligne comme décrit dans Activation et désactivation des modes pour une partie seulement de l'expression régulière :

Le regex (?i)te(?-i)stdoit correspondre à test et TEst, mais pas teSTou TEST.

Cependant, une fonctionnalité un peu plus prise en charge est un (?i:...)groupe de modificateurs en ligne (voir Étendues de modificateurs ). La syntaxe est (?i:, puis le modèle que vous souhaitez rendre insensible à la casse, puis a ).

(?i:foo)|BAR

L'inverse : Si votre modèle est compilé avec un cas , l' option insensible et vous devez faire partie d'un cas regex sensible, vous ajoutez -après ?: (?-i:...).

Exemple d'utilisation dans différentes langues (encapsulation des correspondances avec des chevrons):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( démo )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( démo ) (notez que Python reprend en charge les groupes de modificateurs en ligne depuis Python 3.6)
  • / / - Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>")( démo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")( démo )
  • - $s =~ s/(?i:foo)|BAR/<$&>/g( démo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')( démo )
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)( démo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (utilise RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( démo )

Non pris en charge dans , , , std::regex, , .

Wiktor Stribiżew
la source