我有用于字符串替换的自定义格式化程序,它应该仅与替换字段语法中的标准字符串格式化程序不同:而不是'{f}'.format(f=123)
我想要'$(f)'.format(f=123)
的(后者实际上将使用自定义格式化程序类,如shell_formatter.format(...)
)。
我覆盖了string.Formatter.parse
使用新语法,但我最终使用的正则表达式并不能让我很满意。
问题:
- 我可以让正则表达式更简单/更具可读性吗?
- 有没有更简单的方法来更改我错过的格式语法?
更新
- 简化了正则表达式并添加了新的测试。
- 目的是从模板生成 C 源代码文件。由于 C 过度使用卷曲,因此在这里使用
'{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()