您可以使用空格作为分隔符来利用 shell 的命令行解析器:
$ myscript --replace=foo bar \
> --replace=/etc/hosts /etc/foo gi \
> --replace=test@email.com root@email.com
g
标志在 Python 中是默认的,因此您需要为其添加特殊支持:
#!/usr/bin/env python
import re
from argparse import ArgumentParser
from functools import partial
all_re_flags = 'Lgimsux' # regex flags
parser = ArgumentParser(usage='%(prog)s [--replace PATTERN REPL [FLAGS]]...')
parser.add_argument('-e', '--replace', action='append', nargs='*')
args = parser.parse_args()
print(args.replace)
subs = [] # replacement functions: input string -> result
for arg in args.replace:
count = 1 # replace only the first occurrence if no `g` flag
if len(arg) == 2:
pattern, repl = arg
elif len(arg) == 3:
pattern, repl, flags = arg
if ''.join(sorted(flags)) not in all_re_flags:
parser.error('invalid flags %r for --replace option' % flags)
if 'g' in flags: # add support for `g` flag
flags = flags.replace('g', '')
count = 0 # replace all occurrences
if flags: # embed flags
pattern = "(?%s)%s" % (flags, pattern)
else:
parser.error('wrong number of arguments for --replace option')
subs.append(partial(re.compile(pattern).sub, repl, count=count))
你可以使用subs
如下:
input_string = 'a b a b'
for replace in subs:
print(replace(input_string))
例子:
$ ./myscript -e 'a b' 'no flag' -e 'a B' 'with flags' ig
输出:
[['a b', 'no flag'], ['a B', 'with flags', 'ig']]
no flag a b
with flags with flags