¿Puedes hacer que solo una parte de una expresión regular no distinga entre mayúsculas y minúsculas?

100

He visto muchos ejemplos de cómo hacer que una expresión regular completa no distinga entre mayúsculas y minúsculas. Lo que me pregunto es que solo una parte de la expresión no distinga entre mayúsculas y minúsculas.

Por ejemplo, digamos que tengo una cadena como esta:

fooFOOfOoFoOBARBARbarbarbAr

¿Qué sucede si quiero hacer coincidir todas las apariciones de "foo" independientemente de las mayúsculas y minúsculas, pero solo quiero hacer coincidir las "BAR" en mayúsculas?

La solución ideal sería algo que funcione en todos los sabores de expresiones regulares, pero también estoy interesado en escuchar los específicos del idioma (Gracias Espo )

Editar

El enlace proporcionado por Espo fue muy útil. Hay un buen ejemplo sobre cómo activar y desactivar modificadores dentro de la expresión.

Para mi ejemplo artificial, puedo hacer algo como esto:

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

lo que hace que la coincidencia no distinga entre mayúsculas y minúsculas solo para la parte foo de la coincidencia.

Eso parecía funcionar en la mayoría de las implementaciones de expresiones regulares, excepto Javascript, Python y algunas otras (como mencionó Espo).

Los grandes sobre los que me preguntaba (Perl, PHP, .NET) admiten cambios de modo en línea.

Mark Biek
fuente
Esta pregunta se ha agregado a las preguntas frecuentes sobre expresiones regulares de desbordamiento de pila , en "Modificadores".
aliteralmind

Respuestas:

88

Perl le permite hacer que parte de su expresión regular no distinga entre mayúsculas y minúsculas utilizando el modificador de patrón (? I :).

Los sabores de expresiones regulares modernas le permiten aplicar modificadores solo a una parte de la expresión regular. Si inserta el modificador (? Ism) en el medio de la expresión regular, el modificador solo se aplica a la parte de la expresión regular a la derecha del modificador. Puede desactivar los modos precediéndolos con un signo menos. Todos los modos después del signo menos se apagarán. Por ejemplo, (? I-sm) activa la insensibilidad a mayúsculas y minúsculas y desactiva el modo de una sola línea y el modo de varias líneas.

No todos los sabores de expresiones regulares admiten esto. JavaScript y Python aplican todos los modificadores de modo a toda la expresión regular. No admiten la sintaxis (? -Ismx), ya que desactivar una opción no tiene sentido cuando los modificadores de modo se aplican a todas las expresiones regulares. Todas las opciones están desactivadas de forma predeterminada.

Puede probar rápidamente cómo el sabor de expresiones regulares que está utilizando maneja los modificadores de modo. La expresión regular (? I) te (? - i) st debe coincidir con la prueba y la prueba, pero no la prueba o la prueba.

Fuente

Espo
fuente
6

Qué idioma estás usando? Una forma estándar de hacer esto sería algo como / ([Ff] [Oo] {2} | BAR) / con distinción entre mayúsculas y minúsculas activada, pero en Java, por ejemplo, hay un modificador de distinción entre mayúsculas y minúsculas (? I) que hace que todos los caracteres a la derecha no distinguen entre mayúsculas y minúsculas y (? -i) que fuerza la sensibilidad. Puede encontrar un ejemplo de ese modificador de expresiones regulares de Java aquí .

akdom
fuente
+1 ¿Por qué molestarse en hacer que no
distinga entre
11
@NonaUrbiz: Porque la expresión (?i)foobares más legible que[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos
1
Y debido a que puede crecer manera mucho más peludo y compleja.
Chop
6

Desafortunadamente, la sintaxis para la coincidencia que no distingue entre mayúsculas y minúsculas no es común. En .NET puede usar RegexOptions.IgnoreCase flag o modificador ? I

aku
fuente
4

Podrías usar

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

El?: Entre paréntesis en .Net significa que no captura y solo se usa para agrupar los términos de | (o) declaración.

Kibbee
fuente
26
¿No es "[fF] [oO] [oO]" la mejor alternativa? Para el ejemplo que nos ocupa, incluso podría ir tan lejos como "[fF] [oO] \ {2}" ;-)
Tomalak
4

Es cierto que uno puede confiar en modificadores en línea como se describe en Activar y desactivar modos para solo una parte de la expresión regular :

La expresión regular (?i)te(?-i)stdebe coincidir con la prueba y TEst, pero no con la teSTo TEST.

Sin embargo, una característica un poco más admitida es un (?i:...)grupo de modificadores en línea (consulte Intervalos de modificadores ). La sintaxis es (?i:, luego el patrón que desea hacer insensible a mayúsculas, y luego a ).

(?i:foo)|BAR

La inversa : si el patrón es compilado con la opción de mayúsculas y minúsculas y hay que hacer una parte de un caso de expresiones regulares sensible, añadir -después ?: (?-i:...).

Ejemplos de usos en varios idiomas (entre paréntesis angulares):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( demostración )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( demostración ) (tenga en cuenta que Python readmite grupos de modificadores en línea desde Python 3.6)
  • / / - Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>")( demostración )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")( demostración )
  • - $s =~ s/(?i:foo)|BAR/<$&>/g( demostración )
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')( demostración )
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)( demostración )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (usa RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( demo )

No admitido en , , , std::regex, , .

Wiktor Stribiżew
fuente