¿Cómo quitar la parte izquierda de una cadena?

Tengo un código Python simple que busca archivos en una cadena, por ejemplo, path=c:\path , por lo que la c:\path puede variar. El código actual es:

 def findPath( i_file) : lines = open( i_file ).readlines() for line in lines : if line.startswith( "Path=" ) : return # what to do here in order to get line content after "Path=" ? 

¿Cuál es una forma sencilla de obtener un texto de cadena después de Path= ? ¿Existe un método simple, sin cierres, reflexión u otras cosas esotéricas?

Si la cadena es fija, simplemente puede usar:

 if line.startswith("Path="): return line[5:] 

que le da todo desde la posición 5 en la cadena (una cadena también es una secuencia, por lo que estos operadores de secuencia también funcionan aquí).

O puedes dividir la línea en la primera = :

 if "=" in line: param, value = line.split("=",1) 

Entonces param es “Path” y valor es el rest después de la primera =.

Eliminar prefijo de una cadena

 # ... if line.startswith(prefix): return line[len(prefix):] 

Dividir en la primera aparición del separador a través de str.partition()

 def findvar(filename, varname="Path", sep="=") : for line in open(filename): if line.startswith(varname + sep): head, sep_, tail = line.partition(sep) # instead of `str.split()` assert head == varname assert sep_ == sep return tail 

Parse INI-como archivo con ConfigParser

 from ConfigParser import SafeConfigParser config = SafeConfigParser() config.read(filename) # requires section headers to be present path = config.get(section, 'path', raw=1) # case-insensitive, no interpolation 

Otras opciones

  • str.split()
  • re.match()

Para rebanar (condicional o no condicional) en general, prefiero lo que sugirió un colega recientemente; Utilice el reemplazo con una cadena vacía. Más fácil de leer el código, menos código (a veces) y menos riesgo de especificar el número incorrecto de caracteres. De acuerdo; No uso Python, pero en otros idiomas prefiero este enfoque:

 rightmost = full_path.replace('Path=', '', 1) 

o – para continuar con el primer comentario de esta publicación – si esto solo se debe hacer si la línea comienza con Path :

 rightmost = re.compile('^Path=').sub('', full_path) 

La diferencia principal con respecto a lo que se ha sugerido anteriormente es que no hay un “número mágico” (5), ni ninguna necesidad de especificar tanto ‘ 5como la cadena ‘ Path= ‘, en otras palabras, prefiero este enfoque desde Un punto de vista de mantenimiento de código.

 def remove_prefix(text, prefix): return text[len(prefix):] if text.startswith(prefix) else text 

No pude resistirme a hacer esto en una línea. Requiere Python 2.5+.

Prefiero el pop a la indexación [-1] :

 value = line.split("Path=", 1).pop() 

a

 value = line.split("Path=", 1)[1] param, value = line.split("Path=", 1) 

O porque no

 if line.startswith(prefix): return line.replace(prefix, '', 1) 

Qué tal si..

 >>> line = r'path=c:\path' >>> line.partition('path=') ('', 'path=', 'c:\\path') 

Este triplete es la cabeza, el separador y la cola .

 >>> import re >>> p = re.compile(r'path=(.*)', re.IGNORECASE) >>> path = "path=c:\path" >>> re.match(p, path).group(1) 'c:\\path' 

La forma más sencilla que puedo pensar es con rebanar

 def findPath( i_file): lines = open( i_file ).readlines() for line in lines: if line.startswith( "Path=" ) : return line[5:] 

Una nota rápida sobre notación de división, utiliza dos índices en lugar de los habituales. El primer índice indica el primer elemento de la secuencia que desea incluir en el sector y el último índice es el índice inmediatamente después del último elemento que desea incluir en el sector.
P.ej:

 sequenceObj[firstIndex:lastIndex] 

El sector consta de todos los elementos entre firstIndex y lastIndex , incluidos firstIndex y no lastIndex . Si se omite el primer índice, el inicio de la secuencia es predeterminado. Si se omite el último índice, incluye todos los elementos hasta el último elemento de la secuencia. También se permiten índices negativos. Usa Google para aprender más sobre el tema.

Otro sencillo de una sola línea que no se ha mencionado aquí:

 value = line.split("Path=", 1)[-1] 

Esto también funcionará correctamente para varios casos de borde:

 >>> print("prefixfoobar".split("foo", 1)[-1]) "bar" >>> print("foofoobar".split("foo", 1)[-1]) "foobar" >>> print("foobar".split("foo", 1)[-1]) "bar" >>> print("bar".split("foo", 1)[-1]) "bar" >>> print("".split("foo", 1)[-1]) "" 
 line[5:] 

Te da personajes después de los primeros cinco.

line[5:] le dará la subcadena que desee. Busque la introducción y busque ‘notación de corte’

La versión pop no estaba del todo bien. Creo que quieres:

 >>> print('foofoobar'.split('foo', 1).pop()) foobar 

Supongo que esto es lo que estás buscando exactamente.

  def findPath(i_file) : lines = open( i_file ).readlines() for line in lines : if line.startswith( "Path=" ): output_line=line[(line.find("Path=")+len("Path=")):] return output_line 

Si sabes enumerar las comprensiones:

 lines = [line[5:] for line in file.readlines() if line[:5] == "Path="] 

sin tener que escribir una función, se dividirá de acuerdo con la lista, en este caso ‘Sr. | Dr. | Sra.’, seleccione todo después de dividir con [1], luego divida nuevamente y tome cualquier elemento. En el caso a continuación, se devuelve ‘Morris’.

 re.split('Mr.|Dr.|Mrs.', 'Mr. Morgan Morris')[1].split()[1] 

¿Por qué no usar regex con escape? ^ coincide con la parte inicial de una línea y re.MULTILINE coincide en cada línea. re.escape asegura que la coincidencia es exacta.

 >>> print(re.sub('^' + re.escape('path='), repl='', string='path=c:\path\nd:\path2', flags=re.MULTILINE)) c:\path d:\path2