Come si esegue un'espressione regolare senza distinzione tra maiuscole e minuscole in Go?


85

Ora, ovviamente, potrei scrivere la mia espressione regolare per gestire entrambi i casi, ad esempio regexp.Compile("[a-zA-Z]"), ma la mia espressione regolare è costruita da una stringa data dall'utente:

reg, err := regexp.Compile(strings.Replace(s.Name, " ", "[ \\._-]", -1))

Dov'è s.Nameil nome. Potrebbe essere qualcosa come "North by Northwest". Ora, la soluzione più evidente per me sarebbe passare attraverso ogni carattere di s.Namee scrivere '[nN]' per ogni lettera:

for i := 0; i < len(s.Name); i++ {
  if s.Name[i] == " " {
    fmt.Fprintf(str, "%s[ \\._-]", str);
  } else {
    fmt.Fprintf(str, "%s[%s%s]", str, strings.ToLower(s.Name[i]), strings.ToUpper(s.Name[i]))
  }
}

Ma credo che questa sia una soluzione piuttosto non elegante. La velocità non è davvero un problema, ma ho bisogno di sapere se c'è un altro modo.

Risposte:


171

È possibile impostare un flag senza distinzione tra maiuscole e minuscole come primo elemento nella regex.

Puoi farlo aggiungendo "(?i)"all'inizio di una regex.

reg, err := regexp.Compile("(?i)"+strings.Replace(s.Name, " ", "[ \\._-]", -1))

Per una regex fissa sarebbe simile a questa.

r := regexp.MustCompile(`(?i)CaSe`)

Per ulteriori informazioni sui flag, cercare nella regexp/syntaxdocumentazione del pacchetto (o nella documentazione della sintassi ) il termine "flag".


4
Ma ho scoperto che è troppo lento, quando ci sono molti dati. A causa dell'invocazione di unicode.SimpleFold in regexp.Match, quindi suggerisco di cambiare le lettere in alto e quindi di utilizzare regexp per abbinare. Questa è la velocità. Di seguito sono riportati i dati temporali: `` #By (? I) regexp per ignorare il caso XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / frameworks -f Codice / frameworks 1271.94s utente 7.32s sistema 97% cpu 21: 54.95 totale #By toUpper e abbina XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / frameworks -f Codice / frameworks 263.87s utente 8.99s sistema 110% cpu 4: 06.44 totale ``
QJGui

1
Sembra che le prestazioni lente per le espressioni regolari senza distinzione tra maiuscole e minuscole fossero un bug noto che è stato risolto nei mesi seguenti: github.com/golang/go/issues/13288
Dan Esparza,

29

È possibile aggiungere un (?i)all'inizio del modello per renderlo insensibile al maiuscolo / minuscolo.

Riferimento



4

Usa la ibandiera. Citando la documentazione del suggerimento :

Raggruppamento:

(re)           numbered capturing group
(?P<name>re)   named & numbered capturing group
(?:re)         non-capturing group
(?flags)       set flags within current group; non-capturing
(?flags:re)    set flags during re; non-capturing

La sintassi dei flag è xyz (set) o -xyz (clear) o xy-z (set xy, clear z). Le bandiere sono:

i              case-insensitive (default false)
m              multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)
s              let . match \n (default false)
U              ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false)

23
Dove nel codice devo inserire questi i, m, se U?
Qian Chen

26
Questa risposta è inutile quanto la documentazione. Per fortuna, c'è un esempio funzionante di seguito.
laurent
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.