Python标准库之String模板

大家好,字符串模块可以追溯到Python的最早版本。以前在这个模块中实现的许多函数都被转移到了str对象的方法中,string模块保留了几个用于处理str对象的有用常量和类,包括capwords()字母大小写转化,split()字符串拆分,join()字符串合并等。

1.模板

字符串模板是作为PEP 292的一部分添加的,旨在作为内置插值语法的替代。使用string.Template插值,变量通过在名称前面加$(例如,$var)来标识。或者,如果需要将它们与周围的文本分开,也可以用花括号(例如,${var})将它们包裹起来。

本例使用%运算符将简单模板与类似的字符串插值进行比较,并使用str.format将新格式字符串语法进行比较。

# string_template.py
import string

values = {'var': 'foo'}

t = string.Template("""
Variable        : $var
Escape          : $$
Variable in text: ${var}iable
""")

print('TEMPLATE:', t.substitute(values))

s = """
Variable        : %(var)s
Escape          : %%
Variable in text: %(var)siable
"""

print('INTERPOLATION:', s % values)

s = """
Variable        : {var}
Escape          : {{}}
Variable in text: {var}iable
"""

print('FORMAT:', s.format(**values))

在前两种情况下,触发器字符($或%)通过重复两次进行转义。对于格式语法,{和}都需要通过重复进行转义。

# string_template.py输出结果
TEMPLATE:
Variable        : foo
Escape          : $
Variable in text: fooiable

INTERPOLATION:
Variable        : foo
Escape          : %
Variable in text: fooiable

FORMAT:
Variable        : foo
Escape          : {}
Variable in text: fooiable

模板和字符串插值或格式化之间的一个关键区别是,参数的类型没有考虑在内。值被转换为字符串,字符串被插入到结果中。没有可用的格式选项,例如,无法控制用于表示浮点值的位数。

但是,如果不是模板所需的所有值都作为参数提供,那么使用safe_substitute()方法可以避免异常。

# string_template_missing.py
import string

values = {'var': 'foo'}

t = string.Template("$var is here but $missing is not provided")

try:
    print('substitute()     :', t.substitute(values))
except KeyError as err:
    print('ERROR:', str(err))

print('safe_substitute():', t.safe_substitute(values))

代码片段:可切换语言,无法单独设置文字格式

由于值字典中没有缺少的值,因此substitute()会引发KeyError。safe_substitute没有引发错误,而是捕捉到错误,并将变量表达式单独留在文本中。

# string_template_missing.py输出
ERROR: 'missing'
safe_substitute(): foo is here but $missing is not provided

2.模板进阶

字符串的默认语法,可以使用正则表达式,在模板中查找变量名进行更改。一种简单的方法是更改分隔符和idpattern类属性。

# string_template_advanced.py
import string

class MyTemplate(string.Template):
    delimiter = '%'
    idpattern = '[a-z]+_[a-z]+'

template_text = '''
  Delimiter : %%
  Replaced  : %with_underscore
  Ignored   : %notunderscored
'''

d = {
    'with_underscore': 'replaced',
    'notunderscored': 'not replaced',
}

t = MyTemplate(template_text)
print('Modified ID pattern:')
print(t.safe_substitute(d))

本实例中替换规则已更改,因此分隔符是%而不是$,并且变量名必须在中间包含下划线。模式%notunderlined不会被任何内容替换,因为它不包含下划线字符。

# string_template_advanced.py输出
Modified ID pattern:

  Delimiter : %
  Replaced  : replaced
  Ignored   : %notunderscored

对于更复杂的更改,可以重写pattern属性并定义一个全新的正则表达式。提供的模式必须包含四个命名组,用于捕获转义分隔符、命名变量、变量名的括号版本和无效分隔符模式。

# string_template_defaultpattern.py
import string

t = string.Template('$var')
print(t.pattern.pattern)

t.pattern的值是一个已编译的正则表达式,但原始字符串可通过其pattern属性获得。

# string_template_defaultpattern.py输出
\$(?:
  (?P\$) |                # two delimiters
  (?P[_a-z][_a-z0-9]*)    | # identifier
  {(?P[_a-z][_a-z0-9]*)} | # braced identifier
  (?P)                    # ill-formed delimiter exprs
)

这定义了一个新的模式来创建一个新类型的模板,使用{{var}}作为变量语法。

# string_template_newsyntax.py
import re
import string

class MyTemplate(string.Template):
    delimiter = '{{'
    pattern = r'''
    \{\{(?:
    (?P\{\{)|
    (?P[_a-z][_a-z0-9]*)\}\}|
    (?P[_a-z][_a-z0-9]*)\}\}|
    (?P)
    )
    '''

t = MyTemplate('''
{{{{
{{var}}
''')

print('MATCHES:', t.pattern.findall(t.template))
print('SUBSTITUTED:', t.safe_substitute(var='replacement'))

named和braced必须分别提供,即使它们相同。运行示例程序将生成以下输出:

# string_template_newsyntax.py输出
MATCHES: [('{{', '', '', ''), ('', 'var', '', '')]
SUBSTITUTED:
{{
replacement

3.Formatter

Formatter类实现了与str的format方法相同的布局规范语言。它的功能包括强制类型转换、对齐、属性和字段引用、命名和位置模板参数以及特定于类型的格式选项。大多数时候,format方法是这些功能的一个更方便的接口,但Formatter是作为构建子类的一种方式提供的,用于需要变化的情况。

字符串模块包括许多与ASCII和数字字符集相关的常量。

# string_constants.py
import inspect
import string

def is_str(value):
    return isinstance(value, str)

for name, value in inspect.getmembers(string, is_str):
    if name.startswith('_'):
        continue
    print('%s=%r\n' % (name, value))

这些常量在处理ASCII数据时非常有用,但由于遇到某种Unicode形式的非ASCII文本越来越常见,它们的应用受到了限制。

# string_constants.py输出

ascii_letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW
XYZ'

ascii_lowercase='abcdefghijklmnopqrstuvwxyz'

ascii_uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

digits='0123456789'

hexdigits='0123456789abcdefABCDEF'

octdigits='01234567'

printable='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
RSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

punctuation='!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

whitespace=' \t\n\r\x0b\x0c'

你可能感兴趣的:(python,前端,javascript)