2011-04-22 20 views
9

Estoy haciendo un programa de Python que analizará los campos en algunas líneas de entrada. Me gustaría dejar que el usuario ingrese el separador de campo como una opción desde la línea de comando. Estoy usando optparse para hacer esto. Me encuentro con el problema de que escribir algo como \t se separará literalmente en \t, en lugar de en una pestaña, que es lo que quiero. Estoy bastante seguro de que esto es algo de Python y no del caparazón, ya que he probado todas las combinaciones de comillas, barras invertidas y t que se me ocurren.Pasar metacaracteres a Python como argumentos desde la línea de comandos

Si pudiera obtener optparse para que el argumento sea simple (¿existe tal cosa?) En lugar de raw_input, creo que funcionaría. Pero no tengo ni idea de cómo hacer eso.

También he intentado varias sustituciones y trucos con expresiones regulares para convertir la secuencia de los dos caracteres "\t" en la pestaña de un carácter, pero sin éxito.

ejemplo, donde input.txt es:

field 1[tab]field\t2

(Nota: [tab] es un carácter de tabulación y field\t2 es una cadena de 8 caracteres)

parseme.py:

#!/usr/bin/python 
from optparse import OptionParser 
parser = OptionParser() 
parser.add_option("-d", "--delimiter", action="store", type="string", 
    dest="delimiter", default='\t') 
parser.add_option("-f", dest="filename") 
(options, args) = parser.parse_args() 
Infile = open(options.filename, 'r') 
Line = Infile.readline() 

Fields = Line.split(options.delimiter) 
print Fields[0] 
print options.delimiter 

Infile.close() 

Esto me da:

$ parseme.py -f input.txt 
field 1 
[tab] 

Oye, genial, la configuración predeterminada funcionó correctamente. (Sí, ya sé que sólo podía hacer \ t el valor por defecto y olvidarse de él, pero me gustaría saber cómo hacer frente a este tipo de problema.)

$ parseme.py -f input.txt -d '\t' 
field 1[tab]field 
\t 

Esto no es lo que quiero.

Respuesta

6
>>> r'\t\n\v\r'.decode('string-escape') 
'\t\n\x0b\r' 
+0

buena y limpia solución – user237419

+0

Gracias, esto funcionó bien. – Darlingtonia

0

La forma más rápida y sucia es a eval que, de esta manera:

eval(options.delimiter, {}. {}) 

Los predice adicionales vacíos son los que previenen clobbering accidental de su programa.

0

resolverlo desde dentro de su guión:

options.delimiter = re.sub("\\\\t","\t",options.delimiter) 

se puede adaptar el nuevo punto de que coincida con caracteres más escapados (\ n \ r, etc)

otra forma de resolver el problema fuera de pitón :

cuando se llama a la secuencia de comandos de shell, lo hacen así:

parseme.py -f input.txt -d '^V<tab>' 

^V significa "presione Ctrl + V"

a continuación, pulse la pestaña normales clave

esto pasará adecuadamente el carácter de tabulación a la secuencia de comandos de Python;

0

La opción callback es una buena manera de manejar casos difíciles:

parser.add_option("-d", "--delimiter", action="callback", type="string", 
        callback=my_callback, default='\t') 

con la función correspondiente (que se define antes de el analizador, a continuación):

def my_callback(option, opt, value, parser): 
    val = value 
    if value == '\\t': 
     val = '\t' 
    elif value == '\\n': 
     val = '\n' 
    parser.values.delimiter = val 

Puede verificar esto funciona a través de la línea de comando: python test.py -f test.txt -d \t (sin citar el \t, son inútiles)

Tiene la ventaja de manejar la opción a través del módulo 'optparse', no mediante el procesamiento posterior de los resultados del análisis sintáctico.

Cuestiones relacionadas