我有用于字符串替换的自定义格式化程序,它应该与替换字段语法中的标准字符串格式化程序不同:而不是'{f}'.format(f=123)
我想要'$(f)'.format(f=123)
(后者实际上将使用自定义格式化程序类,如shell_formatter.format(...)
)。
我覆盖string.Formatter.parse
以使用新语法,但我最终使用的正则表达式并不能让我满意。
问题:
更新
'{f}'
语法不起作用。string.Template
模块不支持复杂的访问说明符(参见第三个测试)。代码如下:
#! /usr/bin/env python3
import string
import re
class ShellFormatter(string.Formatter):
def parse(self, format_string):
for m in re.finditer(
r"""(?: \$ \( ( [^)]+ ) \) ) # the field access specifier
| (
(?:
\n | . (?= \$ \( ) # any one single character before the '$('
)
| (?:
\n | . (?! \$ \( ) # any one single character, except the one before the '$('
)*
)""",
format_string,
re.VERBOSE):
if m.group(1):
yield ('', m.group(1), '', None)
if m.group(2):
yield (m.group(2), None, None, None)
def main():
...
def test():
s = 'ashyudiqhw $(field) fwekojnwe'
ss = 'checking helll kpoqjkf3483297 18934417 hnhfnqi^$&*@&2 1748912$&#^$\n467812\n^$ jfimopw279\nashyudiqhw $(field) fwekojnwe\njjhjhj$(notfield)'
sss = 'const int complex_stuff = $(stuff[0][field1][field2]);'
sf = ShellFormatter()
assert sf.format(s, field='zzz') == 'ashyudiqhw zzz fwekojnwe'
assert sf.format(ss, field='zzz', notfield='xxx') == 'checking helll kpoqjkf3483297 18934417 hnhfnqi^$&*@&2 1748912$&#^$\n467812\n^$ jfimopw279\nashyudiqhw zzz fwekojnwe\njjhjhjxxx'
assert sf.format(sss, stuff=[ { 'field1': { 'field2': '0x1234' } } ]) == 'const int complex_stuff = 0x1234;'
if __name__ == '__main__':
test()
main()