2011-01-07 9 views
13

Supongamos que tengo una cadena con un montón de cosas al azar en ella como las siguientes:Python encontrar subcadena entre ciertos caracteres utilizando expresiones regulares y reemplazar()

strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl" 

Y estoy interesado en obtener la subcadena sentado entre ' Valor = 'y' & ', que en este ejemplo sería' cinco '.

puedo usar una expresión regular como la siguiente:

match = re.search(r'Value=?([^&>]+)', strJunk) 
>>> print match.group(0) 
Value=five 
>>> print match.group(1) 
five 

¿Cómo es que match.group (0) es todo el asunto '= Valor de cinco' y el grupo (1) es sólo 'cinco'? ¿Y hay una manera para que solo obtenga 'cinco' como único resultado? (Esta pregunta se debe a mí sólo tener un asimiento tenue de expresiones regulares)

También voy a tener que hacer una sustitución en esta cadena, tales como las siguientes:

val1 = match.group(1) 
strJunk.replace(val1, "six", 1)  

que produce:

'asdf2adsf29Value=six&lakl23ljk43asdldl' 

Teniendo en cuenta que planeo realizar las dos tareas anteriores (encontrar la cadena entre 'Value =' y '&', así como reemplazar ese valor) una y otra vez, me preguntaba si hay otras maneras más eficientes de buscar la subcadena y reemplazándolo en la cadena original. Estoy contento con lo que tengo, pero solo quiero asegurarme de no tomar más tiempo de lo que tengo que estar si hay mejores métodos.

Respuesta

9

Los grupos con nombre hacen que sea más fácil obtener los contenidos del grupo posteriormente. Compilar su expresión regular una vez, y luego reutilizar el objeto compilado, será mucho más eficiente que recompilarla para cada uso (que es lo que sucede cuando se llama a re.search repetidamente). Puede usar las afirmaciones positivas de mirar atrás y mirar hacia adelante para hacer que esta expresión regular sea adecuada para la sustitución que desea hacer.

>>> value_regex = re.compile("(?<=Value=)(?P<value>.*?)(?=&)") 
>>> match = value_regex.search(strJunk) 
>>> match.group('value') 
'five' 
>>> value_regex.sub("six", strJunk) 
'asdf2adsf29Value=six&lakl23ljk43asdldl' 
+0

La respuesta de Mahmoud Abelkader también funcionará, siempre y cuando se garantice que "=" y "&" no aparecerán en ningún otro lugar en strJunk. –

2

No estoy seguro si está analizando las URL, en cuyo caso, definitivamente debe usar el módulo urlparse.

Sin embargo, dado que este no es su pregunta, la capacidad de dividir en varios campos utilizando expresiones regulares es extremadamente rápido en Python, por lo que debería ser capaz de hacer lo que quiere de la siguiente manera:

import re 

strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl" 
split_result = re.split(r'[&=]', strJunk) 
split_result[1] = 'six' 
print "{0}={1}&{2}".format(*split_result) 

¡Espero que esto ayude!

EDIT:

Si va a dividir en múltiples ocasiones, puede utilizar re.compile() para compilar la expresión regular. Por lo tanto, tendrá:

import re 
rx_split_on_delimiters = re.compile(r'[&=]') # store this somewhere 

strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl" 
split_result = rx_split_on_delimiters.split(strJunk) 
split_result[1] = 'six' 
print "{0}={1}&{2}".format(*split_result) 
0

¿Cómo es que match.group (0) está todo el asunto '= Valor de cinco' y el grupo (1) es sólo 'cinco'? ¿Y hay una manera para que solo obtenga 'cinco' como único resultado? (Esta pregunta se debe a que solo tengo una tenue comprensión de la expresión regular)

Pensé que mirar detrás de la afirmación puede ayudarte aquí.

>>> match = re.search(r'(?<=Value=)([^&>]+)', strJunk) 
>>> match.group(0) 
'five' 

pero solo puede proporcionar una cadena de longitud constante en la aserción de look behind.

>>> match = re.search(r'(?<=Value=?)([^&>]+)', strJunk) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/re.py", line 142, in search 
    return _compile(pattern, flags).search(string) 
    File "/usr/lib/python2.6/re.py", line 245, in _compile 
    raise error, v # invalid expression 
sre_constants.error: look-behind requires fixed-width pattern 

No puedo dejar de pensar en una forma de hacerlo sin expresiones regulares. Tu forma de hacer esto debería ser más rápida que mirar hacia atrás.

Cuestiones relacionadas