2012-06-13 15 views
12

Ho bisogno di dividere una stringa usando python ma solo sulla prima istanza del delimitatore nella stringa.come dividere una stringa sulla prima istanza del delimitatore in python

Il mio codice:

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

Il problema è line, che contiene jvm.args assomiglia a questo:

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

voglio che il mio codice per dividere jvm.args in variabili chiave e valori tra parentesi alla prima ' ='. Re.split lo fa di default? Se non fosse un suggerimento sarebbe apprezzato!

+1

è possibile inviare l'output di esempio – shiva

+2

Visto che siete interessati solo il primo delimitatore, perché non solo trovare la corrispondenza per il delimitatore, con una scansione della stringa? Quindi puoi semplicemente estrarre le due sezioni con la linea [: pos] e la linea [pos + 1:]. –

+2

Un esempio di output sarebbe d'aiuto. – damned

risposta

25

Questo è quello str.partition è per:

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

Dalla documentazione:

str.partition (SEP)

Split stringa alla prima occorrenza di set, e restituisce una tupla di 3 elementi contenente la parte prima del separatore, il separatore stesso e la parte successiva e separatore. Se il separatore non viene trovato, restituire una tupla 3 contenente la stringa stessa, seguita da con due stringhe vuote.

Novità nella versione 2.5.

+0

+1 - mai saputo di' partition() ' –

+0

+1 metodo migliore, più veloce pure. – jamylak

+0

@jamylak più veloce? –

2

penso che questo dovrebbe funzionare:

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

Come qualcuno ha suggerito nei commenti: si può solo analizzare attraverso stringa una volta e individuare "=", seguito da dividendolo da quel punto.

+0

-1 'value = ','. Join ((chiave," = ". Join (lineSplit [1:])))' è il modo corretto per farlo. –

+2

names_with_underscores sono incoraggiati in python. – jamylak

+0

@jamylak passaggio tra java e python troppo spesso e questo è lo schema che seguo :) Grazie comunque per il suggerimento! – damned

1

Immagino di voler trasformare il mio commento in codice (non verificato) perché potrebbe essere utile a un livello inferiore a str.partition(). Ad esempio, per un delimitatore più complesso che richiede un'espressione regolare, è possibile utilizzare re.match() per trovare pos. Ma il suggerimento di Triptych ha avuto il mio voto.

Qui si va:

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

Dal split documentation

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

Restituisce una lista delle parole nella stringa, usando sep come stringa delimitatore. Se maxsplit è dato, nella maggior parte delle divisioni maxsplit sono fatto (così, la lista avrà al più maxsplit + 1 elementi)

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

mi piacerebbe saltare utilizzando completamente le espressioni regolari, per un semplice confronto di stringhe non sono realmente richiesti.

Il codice di esempio utilizza un metodo in linea di cedere chiave, valore tuple che il comando incorporato dict utilizza per generare un dizionario (non ho disturbato con il codice di iterazione del file, il vostro esempio è corretto là):

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 di stampa torneranno:

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

presumo che ciò è quello che sono in realtà dopo;)

0

Come suggerito nel vostro previous question, ConfigParser i è il modo più semplice:

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') 
Problemi correlati