2012-06-13 22 views
12

Necesito dividir una cadena usando python pero solo en la primera instancia del delimitador en la cadena.cómo dividir una cadena en la primera instancia de delimitador en python

Mi código:

for line in conf.readlines(): 
    if re.search('jvm.args',line): 
     key,value= split('=',line) 
     default_args=val 

El problema es line, que contiene jvm.args se parece a esto:

'jvm.args = -Dappdynamics.com=true, -Dsomeotherparam=false,' 

Quiero mi código para dividir jvm.args en variables clave y valor incidentalmente en la primera ' = '. ¿Re.split hace esto por defecto? ¡Si no, una sugerencia sería apreciada!

+1

Se puede publicar un ejemplo de salida – shiva

+2

Puesto que usted está interesado sólo en el primer delimitador, por qué no acaba de encontrar el partido por el delimitador, con una exploración de la cadena? Luego puede extraer las dos rebanadas con la línea [: pos] y la línea [pos + 1:]. –

+2

Un resultado de muestra ayudaría. – damned

Respuesta

25

Esto es lo que str.partition es para:

>>> 'jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false,'.partition('=') 
('jvm.args', '=', ' -Dappdynamics.com=true, -Dsomeotherparam=false,') 

A partir de los documentos:

str.partition (SEP)

dividir la cadena en la primera aparición de la SEP, y devuelve una 3-tupla que contiene la parte antes del separador, el separador y la parte posterior a e separador. Si no se encuentra el separador , devuelva un 3-tuple que contenga la cadena en sí, seguido de por dos cadenas vacías.

Nuevo en la versión 2.5.

+0

+1 - nunca se supo sobre' partition() ' –

+0

+1 El mejor método, el más rápido también. – jamylak

+0

@jamylak el más rápido? –

2

creo que esto debería funcionar:

lineSplit = line.split("=") 
key = lineSplit[0] 
value = "=".join(lineSplit[1:]) 

Como alguien sugirió en comentarios: sólo se puede analizar a través de la cadena de una vez y localizar "=", seguido de su división desde ese punto.

+0

-1 'value = ','. Join ((key," = ". Join (lineSplit [1:])))' es la forma correcta de hacerlo. –

+2

names_with_underscores se recomiendan en python. – jamylak

+0

@jamylak Cambio entre java y python con demasiada frecuencia y este es el patrón que sigo :) ¡Gracias por su sugerencia! – damned

1

Supongo que convertiré mi comentario en código (no probado) porque podría ser útil en un nivel inferior a str.partition(). Por ejemplo, para un delimitador más complicado que requiera una expresión regular, puede usar re.match() para encontrar pos. Pero la sugerencia de Triptych obtuvo mi voto.

Aquí van:

pos = -1 
for i, ch in enumerate(line): 
    if ch == '=': 
     pos = i 
     break 
if pos < 0: raise myException() 

key = line[:pos] 
value = line[pos+1:] 
10

Desde el split documentation

str.split ([sep [, maxsplit]])

devolver una lista de las palabras de la cadena, usando sep como la cadena del delimitador. Si maxsplit se da, en la mayoría de las divisiones maxsplit se llevan a cabo (por lo tanto, la lista tendrá en la mayoría de 1 elementos maxsplit +)

>>> 'jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false,'.split('=',1) 
['jvm.args', ' -Dappdynamics.com=true, -Dsomeotherparam=false,'] 
0

me olvidaría por completo el uso de expresiones regulares, por una simple comparación de cadenas no son realmente necesarios.

El código de ejemplo utiliza un método en línea para obtener clave, valor tuplas que la orden interna dict utiliza para generar un diccionario (yo no he molestado con el código iteración del archivo, su ejemplo es correcta):

line="jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false, " 

# Detect a line that starts with jvm.args 
if line.strip().startswith('jvm.args'): 
    # Only interested in the args 
    _, _, args = line.partition('=') 

    # Method that will yield a key, value tuple if item can be converted 
    def key_value_iter(args): 
     for arg in args: 
      try: 
       key, value = arg.split('=') 
       # Yield tuple removing the -d prefix from the key 
       yield key.strip()[2:], value 
      except: 
       # A bad or empty value, just ignore these 
       pass 

    # Create a dict based on the yielded key, values 
    args = dict(key_value_iter(args.split(','))) 

args impresión volverán:

{'appdynamics.com': 'true', 'someotherparam': 'false'} 

Supongo que esto es lo que son en realidad después;)

0

Como se sugiere en su previous question, i ConfigParser Es la manera más sencilla:

import ConfigParser 

from io import StringIO 

conf = u""" 
[options] 
foo=bar 
jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false, 
""" 

config = ConfigParser.ConfigParser() 
config.readfp(StringIO(conf)) 
print config.get('options', 'jvm.args') 
Cuestiones relacionadas