Como dice el título: ¿Cuál es la mejor manera de convertir una cadena de mayúsculas a minúsculas manteniendo una parte sin cambios? p.ej. una cadena como: FormatDate(%M)==2 o stArTDate(%Y/%m)==11/3 y quiero convertirla en formatdate(%M)==2 o startdate(%Y/%m)==11/3, es decir, cambiarla a minúsculas, excepto la parte entre las llaves () . Para el primer ejemplo, se me ocurrió algo como esto:

>>> import re
>>> fdt = re.compile('(F|f)(O|o)(R|r)(M|m)(A|a)(T|t)(D|d)(A|a)(T|t)(E|e)\(')
>>> ss = "forMatDate(%M)==2"
>>> if fdt.match(ss):
...   SS = ss.split('(')
...   SS[0] = SS[0].lower()
...   ss = "(".join(SS)
... 
>>> print ss
formatdate(%M)==2

Si bien funciona bien, no me gustó hacerlo de esta manera. La expresión regular es fea y hace que las cosas se restrinjan bastante a una cadena particular. ¿Hay alguna forma mejor (por lo tanto, dinámica) de hacerlo? Gracias por adelantado. ¡¡Salud!!


Actualizar:

Probablemente no lo dije muy claramente: no siempre es formatdate(), a veces es startdate() o enddate() junto con UserName==JohnDee y así sucesivamente ... (es parte del usuario -input) pero el formato es siempre el mismo y quería algo reutilizable. Entonces, esta es la versión actualizada basada en el script Krumelur's.

>>> fdt = re.compile('\(%[dmwyMW].*\)')
>>> ss = "formatDate(%M)==4"
>>> st = "UserName==JohnDee"
>>>
>>> def dt_lower(sX):
...   if fdt.search(sX):
...     p1,p2 = sX.split('(',1)
...     sX = "%s(%s" % (p1.lower(), p2)
...   else: sX = sX.lower()
...   return sX
... 
>>> print dt_lower(ss)
formatdate(%M)==4
>>>
>>> print dt_lower(st)
username==johndee

Esto es exactamente lo que quería. Gracias a todos por ayudar. ¡¡Salud!!

3
MacUsers 2 jun. 2011 a las 13:53

5 respuestas

La mejor respuesta

¿Tus cuerdas siempre se ven exactamente así? Si es así, tal vez esto sea suficiente:

p1,p2 = instr.split('(',1)
lc = '%s(%s' % (p1.lower(), p2)
5
Krumelur 7 jun. 2011 a las 07:16

Solo para agregar a la respuesta de Krumerlur, es posible que desee hacerlo

p1,p2 = inst.split( '(' , 1 )

2
elricL 2 jun. 2011 a las 10:07

Realmente no entiendo por qué estás usando una expresión regular. ¿Por qué no lo haces?

x, y = ss.split('(')
'('.join((x.lower(), y))
2
zeekay 2 jun. 2011 a las 10:06

No creo que puedas obtener mucho más "Pythonic" que esto:

Python 2.7.1 (r271:86832, May 27 2011, 21:41:45) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ss = "forMatDate(%M)==2"
>>> if ss.lower().startswith('formatdate'):
...     i,j = ss.split('(', 1)
...     ss = '('.join((i.lower(), j))
... 
>>> ss
'formatdate(%M)==2'

No necesita expresiones regulares, solo built-in string methods.

También funciona en Python 3.2.

3
Johnsyweb 2 jun. 2011 a las 10:40

Puede reemplazar su cheque de expresiones regulares con

if ss.lower().startswith('formatdate'):
2
DrTyrsa 2 jun. 2011 a las 10:03