Python: 将旧样式格式模式转换为新样式格式模式
Python: convert old style formatting pattern to new style formatting pattern
是否有一些“内置”方法可以将旧样式格式模式字符串转换为新样式格式。或者最好只使用旧的正则表达式?
例如,我们有模式 '%(a)s - %(b)s'
并希望转换为 '{a} - {b}'
你可以使用 f-strings,只要确保你有 python3.6+
mystring = f'{a} - {b}'
未找到任何用于转换格式的内置 int 解决方案。这是我使用正则表达式实现的方式。
import re
ODD_REPEAT_PATTERN = r'((?<!{c}){c}({c}{c})*(?!{c}))'
EVEN_REPEAT_PATTERN = r'(?<!{c})({c}{c})+(?!{c})'
def __to_new_format(fmt: str, named=True):
def to_named_fmt(fmt):
pattern = rf'{odd_perc_pattern}\((.*?)\)s'
match = re.search(pattern, fmt)
while match:
# Only care about placeholder group here.
__, __, placeholder = match.groups()
fmt = fmt.replace(
f'%({placeholder})s',
f'{{{placeholder}}}'
)
match = re.search(pattern, fmt)
return fmt
def to_pos_fmt(fmt):
even_perc_pattern = EVEN_REPEAT_PATTERN.format(c='%')
pattern = rf'{even_perc_pattern}s'
# When positional placeholder has even amount of percents, it
# will be treated as not having enough arguments passed.
if re.search(pattern, fmt):
raise TypeError(
'not all arguments converted during string formatting'
)
return fmt.replace('%s', '{}')
odd_perc_pattern = ODD_REPEAT_PATTERN.format(c='%')
# Escape `{` and `}`, because new formatting uses it.
fmt = fmt.replace('{', '{{').replace('}', '}}')
fmt = to_named_fmt(fmt) if named else to_pos_fmt(fmt)
# If we find odd number of occurring percentage symbols, it means
# those were not escaped and we can't finish conversion.
if re.search(odd_perc_pattern, fmt):
raise ValueError('incomplete format')
return fmt.replace('%%', '%')
def to_new_named_format(fmt: str) -> str:
"""Convert old style named formatting to new style formatting.
For example: '%(x)s - %%%(y)s' -> '{x} - %{y}'
Args:
fmt: old style formatting to convert.
Returns:
new style formatting.
"""
return __to_new_format(fmt, named=True)
def to_new_pos_format(fmt: str) -> str:
"""Convert old style positional formatting to new style formatting.
For example: '%s - %%%s' -> '{} - %{}'
Args:
fmt: old style formatting to convert.
Returns:
new style formatting.
"""
return __to_new_format(fmt, named=False)
是否有一些“内置”方法可以将旧样式格式模式字符串转换为新样式格式。或者最好只使用旧的正则表达式?
例如,我们有模式 '%(a)s - %(b)s'
并希望转换为 '{a} - {b}'
你可以使用 f-strings,只要确保你有 python3.6+
mystring = f'{a} - {b}'
未找到任何用于转换格式的内置 int 解决方案。这是我使用正则表达式实现的方式。
import re
ODD_REPEAT_PATTERN = r'((?<!{c}){c}({c}{c})*(?!{c}))'
EVEN_REPEAT_PATTERN = r'(?<!{c})({c}{c})+(?!{c})'
def __to_new_format(fmt: str, named=True):
def to_named_fmt(fmt):
pattern = rf'{odd_perc_pattern}\((.*?)\)s'
match = re.search(pattern, fmt)
while match:
# Only care about placeholder group here.
__, __, placeholder = match.groups()
fmt = fmt.replace(
f'%({placeholder})s',
f'{{{placeholder}}}'
)
match = re.search(pattern, fmt)
return fmt
def to_pos_fmt(fmt):
even_perc_pattern = EVEN_REPEAT_PATTERN.format(c='%')
pattern = rf'{even_perc_pattern}s'
# When positional placeholder has even amount of percents, it
# will be treated as not having enough arguments passed.
if re.search(pattern, fmt):
raise TypeError(
'not all arguments converted during string formatting'
)
return fmt.replace('%s', '{}')
odd_perc_pattern = ODD_REPEAT_PATTERN.format(c='%')
# Escape `{` and `}`, because new formatting uses it.
fmt = fmt.replace('{', '{{').replace('}', '}}')
fmt = to_named_fmt(fmt) if named else to_pos_fmt(fmt)
# If we find odd number of occurring percentage symbols, it means
# those were not escaped and we can't finish conversion.
if re.search(odd_perc_pattern, fmt):
raise ValueError('incomplete format')
return fmt.replace('%%', '%')
def to_new_named_format(fmt: str) -> str:
"""Convert old style named formatting to new style formatting.
For example: '%(x)s - %%%(y)s' -> '{x} - %{y}'
Args:
fmt: old style formatting to convert.
Returns:
new style formatting.
"""
return __to_new_format(fmt, named=True)
def to_new_pos_format(fmt: str) -> str:
"""Convert old style positional formatting to new style formatting.
For example: '%s - %%%s' -> '{} - %{}'
Args:
fmt: old style formatting to convert.
Returns:
new style formatting.
"""
return __to_new_format(fmt, named=False)