¿Cómo hago una expresión regular que no distingue entre mayúsculas y minúsculas en Go?

84

Ahora, por supuesto, podría escribir mi expresión regular para manejar ambos casos, por ejemplo regexp.Compile("[a-zA-Z]"), pero mi expresión regular se construye a partir de una cadena dada por el usuario:

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

¿Dónde s.Nameestá el nombre? Que podría ser algo así como "North by Northwest". Ahora, la solución más aparente para mí sería recorrer cada carácter de s.Namey escribir '[nN]' para cada letra:

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]))
  }
}

Pero creo que esta es una solución bastante poco elegante. La velocidad no es realmente una preocupación, pero necesito saber si hay otra forma.

Svip
fuente

Respuestas:

171

Puede establecer una marca que no distinga entre mayúsculas y minúsculas como el primer elemento de la expresión regular.

Haz esto agregando "(?i)"al comienzo de una expresión regular.

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

Para una expresión regular fija, se vería así.

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

Para obtener más información sobre las banderas, busque en la regexp/syntaxdocumentación del paquete (o la documentación de sintaxis ) el término "banderas".

Daniel
fuente
4
Pero descubrí que esto es demasiado lento, cuando hay muchos datos. Debido a que se invoca unicode.SimpleFold en regexp.Match, sugiero cambiar las letras a mayúsculas y luego usar regexp para que coincida. Esta es la velocidad. Los siguientes son datos de tiempo: `` `#Por (? I) regexp para ignorar mayúsculas y minúsculas XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / frameworks -f Code / frameworks 1271.94s usuario 7.32s sistema 97% cpu 21: 54.95 total #By toUpper and match XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / frameworks -f Code / frameworks 263.87s usuario 8.99s sistema 110% cpu 4: 06.44 total ''
QJGui
1
Parece que el rendimiento lento para expresiones regulares que no
Dan Esparza
29

Puede agregar un (?i)al principio del patrón para que no distinga entre mayúsculas y minúsculas.

Referencia

Qtax
fuente
4

Usa la ibandera. Citando la documentación de la sugerencia :

Agrupamiento:

(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 sintaxis de la bandera es xyz (set) o -xyz (clear) o xy-z (set xy, clear z). Las banderas son:

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)
zzzz
fuente
22
¿En qué parte del código debería poner estas i, m, sy U?
Qian Chen
25
Esta respuesta es tan inútil como la documentación. Afortunadamente, hay un ejemplo funcional a continuación.
Laurent