Puoi rendere solo una parte di una regex senza distinzione tra maiuscole e minuscole?


101

Ho visto molti esempi di come rendere un'intera espressione regolare senza distinzione tra maiuscole e minuscole. Quello che mi chiedo è che solo una parte dell'espressione faccia distinzione tra maiuscole e minuscole.

Ad esempio, diciamo che ho una stringa come questa:

fooFOOfOoFoOBARBARbarbarbAr

Che cosa succede se voglio far corrispondere tutte le occorrenze di "foo" indipendentemente dalle maiuscole, ma voglio solo far corrispondere le "BAR" maiuscole?

La soluzione ideale sarebbe qualcosa che funzioni con i gusti delle espressioni regolari, ma mi interessa ascoltare anche quelli specifici della lingua (Grazie Espo )

modificare

Il collegamento fornito da Espo è stato molto utile. C'è un buon esempio di come attivare e disattivare i modificatori all'interno dell'espressione.

Per il mio esempio artificioso, posso fare qualcosa del genere:

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

che rende la corrispondenza senza distinzione tra maiuscole e minuscole solo per la parte foo della corrispondenza.

Sembrava funzionare nella maggior parte delle implementazioni regex tranne Javascript, Python e pochi altri (come menzionato da Espo).

I più grandi su cui mi stavo chiedendo (Perl, PHP, .NET) supportano tutti i cambiamenti della modalità inline.


Questa domanda è stata aggiunta alla FAQ sulle espressioni regolari di Stack Overflow , in "Modificatori".
aliteralmind

Risposte:


88

Perl ti consente di rendere parte della tua espressione regolare senza distinzione tra maiuscole e minuscole utilizzando il modificatore di pattern (? I :).

Le moderne regex ti consentono di applicare modificatori solo a una parte dell'espressione regolare. Se inserisci il modificatore (? Ism) al centro della regex, il modificatore si applica solo alla parte della regex a destra del modificatore. È possibile disattivare le modalità facendole precedere da un segno meno. Tutte le modalità dopo il segno meno verranno disattivate. Ad esempio (? I-sm) attiva l'insensibilità tra maiuscole e minuscole e disattiva sia la modalità riga singola che la modalità multilinea.

Non tutte le versioni regex supportano questo. JavaScript e Python applicano tutti i modificatori di modalità all'intera espressione regolare. Non supportano la sintassi (? -Ismx), poiché disattivare un'opzione è inutile quando i modificatori di modalità si applicano a tutte le espressioni regolari. Tutte le opzioni sono disattivate per impostazione predefinita.

Puoi testare rapidamente come il sapore regex che stai usando gestisce i modificatori della modalità. La regex (? I) te (? - i) st dovrebbe corrispondere a test e TEst, ma non teST o TEST.

fonte


6

Che lingua stai usando? Un modo standard per farlo sarebbe qualcosa come / ([Ff] [Oo] {2} | BAR) / con la distinzione tra maiuscole e minuscole attivata, ma in Java, ad esempio, c'è un modificatore di distinzione tra maiuscole e minuscole (? I) che rende i caratteri a destra non fanno distinzione tra maiuscole e minuscole e (? -i) che forza la sensibilità. Un esempio di quel modificatore di espressioni regolari Java può essere trovato qui .


+1 Perché preoccuparsi di non fare distinzione tra maiuscole e minuscole quando puoi abbinare entrambi i casi
Nona Urbiz,

11
@NonaUrbiz: Perché l'espressione (?i)foobarè più leggibile di[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos

1
E poiché può crescere modo molto più peloso e complesso.
Chop

6

Sfortunatamente la sintassi per la corrispondenza senza distinzione tra maiuscole e minuscole non è comune. In .NET puoi usare il flag RegexOptions.IgnoreCase o il modificatore ? I


4

Potresti usare

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

Il?: Tra parentesi in .Net significa che non è di acquisizione e viene utilizzato solo per raggruppare i termini del | (o) dichiarazione.


26
"[FF] [oO] [oO]" non è l'alternativa migliore? Per l'esempio in questione potresti persino arrivare a "[fF] [oO] \ {2}" ;-)
Tomalak,

4

È vero che si può fare affidamento sui modificatori in linea come descritto in Attivazione e disattivazione delle modalità solo per una parte dell'espressione regolare :

La regex (?i)te(?-i)stdovrebbe corrispondere a test e TEst, ma non teSTo TEST.

Tuttavia, una caratteristica leggermente più supportata è un (?i:...)gruppo di modificatori in linea (vedere Intervalli di modificatori ). La sintassi è (?i:, quindi il modello che si desidera rendere insensibile a cas e quindi un file ).

(?i:foo)|BAR

L'inverso : Se il vostro modello è compilato con un'opzione insensibile caso e avete bisogno di fare una parte di un caso regex sensibile, si aggiunge -dopo ?: (?-i:...).

Esempio di utilizzo in varie lingue (avvolgendo le partite con parentesi angolari):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( demo )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( demo ) (nota Python resupporta i gruppi di modificatori inline da 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])
  • - (utilizza RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( demo )

Non supportato in , , , std::regex, , .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.