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 =.
# ... if line.startswith(prefix): return line[len(prefix):]
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
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
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 ‘ 5
‘ como 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