Discussion:
regex, buscar cadenas con comillas
unknown
2007-12-07 12:30:38 UTC
Permalink
Hola a todos,

Estoy intentando localizar en una string cadenas que van entre comillas.
c = "cadena de ejemplo con 'texto entre comillas'. Fin"
m = re.split("('.*')|(\".*\")", c)
m
['cadena de ejemplo con ', "'texto entre comillas'", None, '. Fin']

Hasta aqui bien (excepto que no entiendo el None).
c = "cadena de ejemplo con 'texto entre comillas' y 'otro texto mas'. Fin"
m = re.split("('.*')|(\".*\")*", c)
m
['cadena de ejemplo con ', "'texto entre comillas' y 'otro texto mas'", None, '. Fin']

En este caso me toma desde la comilla inicial del primer texto hasta el cierre del ultimo como una
sola cadena.

No doy la la expresion correcta. ¿Alguna ayudita?

Gracias.
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-07 12:41:43 UTC
Permalink
Post by unknown
Hola a todos,
Estoy intentando localizar en una string cadenas que van entre comillas.
c = "cadena de ejemplo con 'texto entre comillas'. Fin"
m = re.split("('.*')|(\".*\")", c)
m
['cadena de ejemplo con ', "'texto entre comillas'", None, '. Fin']
Hasta aqui bien (excepto que no entiendo el None).
c = "cadena de ejemplo con 'texto entre comillas' y 'otro texto mas'. Fin"
m = re.split("('.*')|(\".*\")*", c)
m
['cadena de ejemplo con ', "'texto entre comillas' y 'otro texto mas'", None, '. Fin']
En este caso me toma desde la comilla inicial del primer texto hasta el cierre del ultimo como una
sola cadena.
A bote pronto, con que cambies el .* por .*? para hacerlo non-greedy, te
debe funcionar sin problemas.

Puedes hacer un re.finditer(..) para que te vaya devolviendo los
resultados en un iterador... pero vamos, como quieras...
Post by unknown
No doy la la expresion correcta. ¿Alguna ayudita?
Gracias.
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-07 13:00:00 UTC
Permalink
Post by unknown
Post by unknown
Hola a todos,
Estoy intentando localizar en una string cadenas que van entre comillas.
c = "cadena de ejemplo con 'texto entre comillas'. Fin"
m = re.split("('.*')|(\".*\")", c)
m
['cadena de ejemplo con ', "'texto entre comillas'", None, '. Fin']
Hasta aqui bien (excepto que no entiendo el None).
c = "cadena de ejemplo con 'texto entre comillas' y 'otro texto mas'. Fin"
m = re.split("('.*')|(\".*\")*", c)
m
['cadena de ejemplo con ', "'texto entre comillas' y 'otro texto mas'", None, '. Fin']
En este caso me toma desde la comilla inicial del primer texto hasta el cierre del ultimo como una
sola cadena.
A bote pronto, con que cambies el .* por .*? para hacerlo non-greedy, te
debe funcionar sin problemas.
Post by unknown
c = "ejemplo con 'entre comillas', y 'otro mas' y \"un tercero\" Fin"
m = re.split("('.*?')|(\".*?\")", c)
m
['ejemplo con ', "'entre comillas'", None, ', y ', "'otro mas'", None, ' y ', None, '"un tercero"',
' Fin']

Perfecto :)

Gracias.
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-10 14:17:58 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
Hola a todos,
Estoy intentando localizar en una string cadenas que van entre comillas.
c = "cadena de ejemplo con 'texto entre comillas'. Fin"
m = re.split("('.*')|(\".*\")", c)
m
['cadena de ejemplo con ', "'texto entre comillas'", None, '. Fin']
Hasta aqui bien (excepto que no entiendo el None).
c = "cadena de ejemplo con 'texto entre comillas' y 'otro texto mas'. Fin"
m = re.split("('.*')|(\".*\")*", c)
m
['cadena de ejemplo con ', "'texto entre comillas' y 'otro texto mas'", None, '. Fin']
En este caso me toma desde la comilla inicial del primer texto hasta el cierre del ultimo como una
sola cadena.
A bote pronto, con que cambies el .* por .*? para hacerlo non-greedy, te
debe funcionar sin problemas.
Post by unknown
c = "ejemplo con 'entre comillas', y 'otro mas' y \"un tercero\" Fin"
m = re.split("('.*?')|(\".*?\")", c)
m
['ejemplo con ', "'entre comillas'", None, ', y ', "'otro mas'", None, ' y ', None, '"un tercero"',
' Fin']
Perfecto :)
Lo que no entiendo porqué usas .split() para localizar las cadenas. De
ahí se explica que no entiendas porqué te salen los Nones.

En principio, el split tenía que haberte sacado lo siguiente:

['ejemplo con ', ', y ', ' y ', ' Fin']

O sea, te tenía que haber dividido la frase usando el patrón como
separador. Pero al usar grupos de búsquedas (los paréntesis del
patrón), el split incluye en el resultado las cadenas encontrada.
Tienes dos grupos de búsqueda, que es lo que ves. El None indica uno
de los grupos que no ha encontrado.

¿Cómo habría que hacer para no sacara los grupos de búsqueda?
Usando (?:...)

m = re.split("(?:'.*?')|(?:\".*?\")", c)

¿Cómo tienes que hacer para que te dé sólo las cadenas que quieres buscar?

m = re.findall("(?:'.*?')|(?:\".*?\")", c)
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-10 15:31:05 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
Post by unknown
Hola a todos,
Estoy intentando localizar en una string cadenas que van entre comillas.
c = "cadena de ejemplo con 'texto entre comillas'. Fin"
m = re.split("('.*')|(\".*\")", c)
m
['cadena de ejemplo con ', "'texto entre comillas'", None, '. Fin']
Hasta aqui bien (excepto que no entiendo el None).
c = "cadena de ejemplo con 'texto entre comillas' y 'otro texto mas'. Fin"
m = re.split("('.*')|(\".*\")*", c)
m
['cadena de ejemplo con ', "'texto entre comillas' y 'otro texto mas'", None, '. Fin']
En este caso me toma desde la comilla inicial del primer texto hasta el cierre del ultimo como una
sola cadena.
A bote pronto, con que cambies el .* por .*? para hacerlo non-greedy, te
debe funcionar sin problemas.
Post by unknown
c = "ejemplo con 'entre comillas', y 'otro mas' y \"un tercero\" Fin"
m = re.split("('.*?')|(\".*?\")", c)
m
['ejemplo con ', "'entre comillas'", None, ', y ', "'otro mas'", None, ' y ', None, '"un tercero"',
' Fin']
Perfecto :)
Lo que no entiendo porqué usas .split() para localizar las cadenas. De
ahí se explica que no entiendas porqué te salen los Nones.
Lo que pretendia era hacer un replace unicamente en las cadenas que van entre comillas dejando el
resto intacto. El split me parecio una buena idea ya que con esa expresion me devuelve todas las
partes y en su orden.
Se que el regex tiene un 'replace', pero como no soy muy ducho con el, y corria un poquito de prisa
al final quedo asi:

def FiltraSQL(self, sql):
# ajustes en sentencia sql antes de su proceso

# dividir sentencia en fragmentos para modificar los entrecomillados y volver a montar
partes = re.split("('.*?')|(\".*?\")", sql)
# eliminar Nones
while None in partes:
partes.remove(None)

for n,p in zip(range(len(partes)),partes):
if p[0] == "'" or p[0] == '"':
partes[n] = p.replace("*", "%")

return "".join(partes)

Imagino que se podrá optimizar bastante, pero de momento me ha valido.
Post by unknown
['ejemplo con ', ', y ', ' y ', ' Fin']
O sea, te tenía que haber dividido la frase usando el patrón como
separador. Pero al usar grupos de búsquedas (los paréntesis del
patrón), el split incluye en el resultado las cadenas encontrada.
Tienes dos grupos de búsqueda, que es lo que ves. El None indica uno
de los grupos que no ha encontrado.
¿Cómo habría que hacer para no sacara los grupos de búsqueda?
Usando (?:...)
m = re.split("(?:'.*?')|(?:\".*?\")", c)
¿Cómo tienes que hacer para que te dé sólo las cadenas que quieres buscar?
m = re.findall("(?:'.*?')|(?:\".*?\")", c)
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-10 17:01:30 UTC
Permalink
Post by unknown
# ajustes en sentencia sql antes de su proceso
# dividir sentencia en fragmentos para modificar los entrecomillados y volver a montar
partes = re.split("('.*?')|(\".*?\")", sql)
# eliminar Nones
partes.remove(None)
partes[n] = p.replace("*", "%")
return "".join(partes)
Imagino que se podrá optimizar bastante, pero de momento me ha valido.
Y que harás en un caso como almacenar l'enfant ? Es un ejemplo, o tu
sentencia sql incluya un nombre así?

Un saludo.



------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-10 18:21:55 UTC
Permalink
Post by unknown
Post by unknown
# ajustes en sentencia sql antes de su proceso
# dividir sentencia en fragmentos para modificar los entrecomillados y volver a montar
partes = re.split("('.*?')|(\".*?\")", sql)
# eliminar Nones
partes.remove(None)
partes[n] = p.replace("*", "%")
return "".join(partes)
Imagino que se podrá optimizar bastante, pero de momento me ha valido.
Y que harás en un caso como almacenar l'enfant ? Es un ejemplo, o tu
sentencia sql incluya un nombre así?
Post by unknown
re.split("('.*?')|(\".*?\")", "select ... where nombre like \"*l'enfant*\"")
['select ... where nombre like ', None, '"*l\'enfant*"', '']

El problema vendria si la sentencia llegara: .. like 'l'enfant'
En este caso el sql daria error al ejecutarlo aunque que no filtrase, pero eso es problema de la
aplicación que origina el sql. Esta aplicación simplemente recibe una sentencia, la ejecuta y
devuelve el resultado a la aplicación original.

El problema del filtro ha surgido al cambiar el driver de conexión a la base de datos, el anterior
admitia el caracter '*' como comodín para la clausula like mientras que el actual utiliza '%' y
rechaza el antiguo. Nos es mas facil filtrar las sentencias aqui que modificar las diversas
aplicaciones que utilizan este sistema.
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-11 11:50:48 UTC
Permalink
Post by unknown
Lo que pretendia era hacer un replace unicamente en las cadenas que van entre comillas dejando el
resto intacto. El split me parecio una buena idea ya que con esa expresion me devuelve todas las
partes y en su orden.
Se que el regex tiene un 'replace', pero como no soy muy ducho con el, y corria un poquito de prisa
# ajustes en sentencia sql antes de su proceso
# dividir sentencia en fragmentos para modificar los entrecomillados y volver a montar
partes = re.split("('.*?')|(\".*?\")", sql)
# eliminar Nones
partes.remove(None)
partes[n] = p.replace("*", "%")
return "".join(partes)
Imagino que se podrá optimizar bastante, pero de momento me ha valido.
Si ya funciona, no lo arregles; pero si quieres ver cómo se puede hacer mejor:

def repl(m):
return m.group(0).replace("*","%")

sql=re.sub("('.*?')|(\".*?\")", repl, sql)
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
unknown
2007-12-11 14:49:55 UTC
Permalink
Post by unknown
Post by unknown
Lo que pretendia era hacer un replace unicamente en las cadenas que van entre comillas dejando el
resto intacto. El split me parecio una buena idea ya que con esa expresion me devuelve todas las
partes y en su orden.
Se que el regex tiene un 'replace', pero como no soy muy ducho con el, y corria un poquito de prisa
# ajustes en sentencia sql antes de su proceso
# dividir sentencia en fragmentos para modificar los entrecomillados y volver a montar
partes = re.split("('.*?')|(\".*?\")", sql)
# eliminar Nones
partes.remove(None)
partes[n] = p.replace("*", "%")
return "".join(partes)
Imagino que se podrá optimizar bastante, pero de momento me ha valido.
return m.group(0).replace("*","%")
sql=re.sub("('.*?')|(\".*?\")", repl, sql)
Ufff, una verdadera pasada lo que se puede hacer en dos lineas de codigo. ;)
Gracias.
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Loading...