简体   繁体   中英

Python Argparse: Raw string input

Apologies if this has been asked before, I did search for it but all hits seemed to be about python raw strings in general rather than regarding argparse.

Anyways, I have a code where the user feeds in a string and then this string is processed. However, I have a problem as I want my code to be able to differentiate between \\n and \\\\n so that the user can control if they get a line break or \\n appear in the output (respectively).

This in itself is quite simple, and I can get the logic working to check the string, etc. However, argparse doesn't seem to keep the input string raw. So if I were to write: Here is a list:\\nItem 1 it gets parsed as Here is a list:\\\\nItem 1 . As the exact same thing gets parsed if I were to replace \\n with \\\\n in the input string, it becomes impossible to differentiate between the two.

I could include a bodge (for example, I could make the user enter say $\\n for \\n to appear in the output, or just \\n for a line break). But this is messy and complicates the usage of the code.

Is there a way to ensure the string being parsed by argparse is raw? (Ie if I enter \\n it parses \\n and not \\\\n )

Again, sorry if this has been asked before, but I couldn't find an answer and after over an hour of trying to find an answer, I'm out of ideas (bar the bodge). Cheers in advance for any and all help.

Example code (sorry if this doesn't work, not sure how best to do example code for argparse!):

import argparse

parser = argparse.ArgumentParser( description = 'Test.' )
parser.add_argument( 'text', action = 'store', type = str, help = 'The text to parse.' )

args = parser.parse_args( )

print( repr( args.text ) )

Here's a possible solution to your problem:

import argparse

parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('text', action='store', type=str, help='The text to parse.')

args = parser.parse_args()

print '-' * 80
raw_text = eval('"' + args.text.replace('"', '\\"') + '"')
print raw_text
print '-' * 80
print args.text

But be aware of one thing, eval really is dangerous

As noted in the comments, argparse works with sys.argv , a list which is produced by the shell and Python interpreter.

With a simple argv echo script:

0928:~/mypy$ cat echo_argv.py
import sys
print(sys.argv)

I get (with a bash shell):

0929:~/mypy$ python echo_argv.py Here is a list:\nItem 1 
['echo_argv.py', 'Here', 'is', 'a', 'list:nItem', '1']
0931:~/mypy$ python echo_argv.py "Here is a list:\nItem 1 "
['echo_argv.py', 'Here is a list:\\nItem 1 ']
0931:~/mypy$ python echo_argv.py "Here is a list:\\nItem 1 "
['echo_argv.py', 'Here is a list:\\nItem 1 ']

argparse treats that argv as a list of strings. It does nothing to those strings, at least not with the default None type parameter.

As @hpaulj has pointed out, that your problem is originated from the shell and the way sys.argv work. Your option is to handle the string with the escape characters that you got.

Take a look at this answer on SO: Process escape sequences in a string in Python . Basically, use string_escape or unicode_escape to process the string. It is better than hand-handle your string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM