¿Por qué no funciona el indicador ignorecase (re.I) en re.sub ()

Desde pydoc:

re.sub = sub (patrón, respuesta, cadena, cuenta = 0, indicadores = 0)
Devuelva la cadena obtenida reemplazando las repeticiones que no se superponen más a la izquierda del patrón en la cadena por la respuesta de reemplazo. repl puede ser una cadena o un llamable; Si una cadena, la barra invertida se escapa en ella se procesa. Si es una llamada, se pasa el objeto coincidente y debe devolver una cadena de reemplazo para ser utilizada.

código de ejemplo:

import re print re.sub('class', 'function', 'Class object', re.I) 

No se realiza ningún reemplazo a menos que cambie el patrón a ‘Clase’.

La documentación no menciona nada sobre esta limitación, así que asumo que puedo estar haciendo algo mal.

¿Cuál es el caso aquí?

Me parece que deberías estar haciendo:

 import re print re.sub('class', 'function', 'Class object', flags=re.I) 

Sin esto, el argumento re.I se pasa al argumento count .

El argumento flags es el quinto : estás pasando el valor de re.I como el argumento count (un error fácil de cometer).

Nota para aquellos que todavía se ocupan de las instalaciones de Python 2.6.x o anteriores. La documentación de Python para 2.6 re dice:

 re.sub(pattern, repl, string[, count]) re.compile(pattern[, flags]) 

Esto significa que no puedes pasar banderas directamente a sub. Solo se pueden utilizar con comstackción:

 regex = re.compile('class', re.I) regex.sub("function", "Class object") 

Para evitar errores de este tipo, se pueden usar los siguientes parches de mono:

 import re re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \ _fun(pattern, repl, string, count=count, flags=flags) 

( * es para prohibir la especificación de count , las _fun=re.sub como argumentos posicionales. _fun=re.sub es usar la statement en tiempo re.sub .)

Manifestación:

 $ python Python 3.4.2 (default, Oct 8 2014, 10:45:20) [GCC 4.9.1] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import re >>> re.sub(r'\b or \b', ',', 'or x', re.X) 'or x' # ?! >>> re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \ ... _fun(pattern, repl, string, count=count, flags=flags) >>> re.sub(r'\b or \b', ',', 'or x', re.X) Traceback (most recent call last): File "", line 1, in  TypeError: () takes 3 positional arguments but 4 were given >>> re.sub(r'\b or \b', ',', 'or x', flags=re.X) ', x' >>> 

Solo para agregar a la respuesta de Seppo. De acuerdo con http://docs.python.org/2.6/library/re.html , todavía hay una manera de pasar las banderas directamente a ‘sub’ en 2.6, lo que podría ser útil si tiene que hacer un código 2.7 con mucho de sub compatibles con 2.6. Para citar el manual:

… si necesita especificar banderas de expresión regular, debe usar un objeto RE o usar modificadores incrustados en un patrón; por ejemplo, sub (“(? i) b +”, “x”, “bbbb BBBB”) devuelve ‘x x’

y

(? iLmsux) (Una o más letras del conjunto ‘i’, ‘L’, ‘m’, ‘s’, ‘u’, ‘x’.) El grupo coincide con la cadena vacía; las letras establecen los indicadores correspondientes: re.I (ignorar mayúsculas y minúsculas), re.L (dependiente del entorno local), re.M (multilínea), re.S (punto coincide con todo), re.U (dependiente de Unicode) y re.X (verbose), para toda la expresión regular. (Los indicadores se describen en Contenido del módulo). Esto es útil si desea incluir los indicadores como parte de la expresión regular, en lugar de pasar un argumento de indicador a la función re.compile ().

En la práctica, esto significa

print re.sub("class", "function", "Class object", flags= re.IGNORECASE)

se puede reescribir usando modificadores (? ms) como

print re.sub("(?i)class", "function", "Class object")