¿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.

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".


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



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)

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.