string — 常见的字符串操作

源代码: Lib/string.py


字符串常量

本模块中定义的常量有

string.ascii_letters

下面描述的 ascii_lowercaseascii_uppercase 常量的串联。此值不依赖于区域设置。

string.ascii_lowercase

小写字母 'abcdefghijklmnopqrstuvwxyz'。此值不依赖于区域设置,且不会改变。

string.ascii_uppercase

大写字母 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'。此值不依赖于区域设置,且不会改变。

string.digits

字符串 '0123456789'

string.hexdigits

字符串 '0123456789abcdefABCDEF'

string.octdigits

字符串 '01234567'

string.punctuation

C 区域设置中被认为是标点符号的 ASCII 字符字符串:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

string.printable

Python 认为是可打印的 ASCII 字符字符串。这是 digitsascii_letterspunctuationwhitespace 的组合。

备注

根据设计,string.printable.isprintable() 返回 False。特别是,string.printable 在 POSIX 意义上是不可打印的(参见 LC_CTYPE)。

string.whitespace

一个包含所有被认为是空白字符的 ASCII 字符的字符串。这包括空格、制表符、换行符、回车符、换页符和垂直制表符。

自定义字符串格式化

内置字符串类通过 PEP 3101 中描述的 format() 方法,提供了复杂的变量替换和值格式化功能。string 模块中的 Formatter 类允许您使用与内置 format() 方法相同的实现来创建和自定义您自己的字符串格式化行为。

class string.Formatter

Formatter 类具有以下公共方法

format(format_string, /, *args, **kwargs)

主要 API 方法。它接受一个格式字符串和一组任意的位置参数和关键字参数。它只是一个调用 vformat() 的包装器。

3.7 版本发生变化: 格式字符串参数现在是 仅限位置 的。

vformat(format_string, args, kwargs)

此函数执行实际的格式化工作。它作为单独的函数公开,适用于您想要传入预定义参数字典,而不是使用 *args**kwargs 语法解包和重新打包字典作为单个参数的情况。vformat() 负责将格式字符串分解为字符数据和替换字段。它调用下面描述的各种方法。

此外,Formatter 定义了许多旨在被子类替换的方法

parse(format_string)

遍历 format_string 并返回一个元组可迭代对象 (literal_text, field_name, format_spec, conversion)。这由 vformat() 用于将字符串分解为字面文本或替换字段。

元组中的值在概念上表示一段字面文本,后跟一个替换字段。如果没有字面文本(如果两个替换字段连续出现,可能会发生这种情况),则 literal_text 将是零长度字符串。如果没有替换字段,则 field_nameformat_specconversion 的值将为 Nonefield_name 的值未修改,非编号位置字段的自动编号由 vformat() 完成。

get_field(field_name, args, kwargs)

给定 field_name,将其转换为要格式化的对象。parse() 返回的 field_name 的自动编号在调用此方法之前由 vformat() 完成。返回一个元组 (obj, used_key)。默认版本采用 PEP 3101 中定义的字符串形式,例如“0[name]”或“label.title”。argskwargs 是作为参数传递给 vformat() 的。返回值 used_keyget_value()key 参数具有相同的含义。

get_value(key, args, kwargs)

检索给定的字段值。key 参数将是整数或字符串。如果是整数,它表示 args 中位置参数的索引;如果是字符串,则表示 kwargs 中的命名参数。

args 参数设置为 vformat() 的位置参数列表,kwargs 参数设置为关键字参数字典。

对于复合字段名,这些函数仅针对字段名的第一个组件调用;后续组件通过正常的属性和索引操作处理。

因此,例如,字段表达式“0.name”将导致 get_value() 被调用,其中 key 参数为 0。在 get_value() 返回后,将通过调用内置的 getattr() 函数来查找 name 属性。

如果索引或关键字引用了不存在的项,则应引发 IndexErrorKeyError

check_unused_args(used_args, args, kwargs)

如果需要,实现检查未使用的参数。此函数的参数是格式字符串中实际引用的所有参数键的集合(位置参数的整数,命名参数的字符串),以及传递给 vformat 的 argskwargs 的引用。可以从这些参数计算出未使用的参数集。check_unused_args() 假定如果检查失败则引发异常。

format_field(value, format_spec)

format_field() 简单地调用全局的 format() 内置函数。提供此方法是为了子类可以覆盖它。

convert_field(value, conversion)

根据转换类型(如 parse() 方法返回的元组)转换值(由 get_field() 返回)。默认版本理解 's' (str)、'r' (repr) 和 'a' (ascii) 转换类型。

格式字符串语法

str.format() 方法和 Formatter 类共享相同的格式字符串语法(尽管在 Formatter 的情况下,子类可以定义自己的格式字符串语法)。该语法与 格式化字符串字面值模板字符串字面值 的语法相关,但它不那么复杂,特别是,不支持插值中的任意表达式。

格式字符串包含由花括号 {} 括起来的“替换字段”。不包含在花括号中的任何内容都被视为字面文本,它被原样复制到输出。如果需要在字面文本中包含花括号字符,可以通过双写来转义:{{}}

替换字段的语法如下

replacement_field: "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name:        arg_name ("." attribute_name | "[" element_index "]")*
arg_name:          [identifier | digit+]
attribute_name:    identifier
element_index:     digit+ | index_string
index_string:      <any source character except "]"> +
conversion:        "r" | "s" | "a"
format_spec:       format-spec:format_spec

用不那么正式的术语来说,替换字段可以以 field_name 开头,该名称指定要格式化并插入到输出中以代替替换字段的对象。field_name 可选地后跟一个 conversion 字段,该字段前面有一个感叹号 '!',以及一个 format_spec,该字段前面有一个冒号 ':'。这些指定替换值的非默认格式。

另请参阅 格式规范迷你语言 部分。

field_name 本身以 arg_name 开头,arg_name 是数字或关键字。如果是数字,它引用位置参数,如果是关键字,它引用命名关键字参数。如果对字符串调用 str.isdecimal() 返回 true,则 arg_name 被视为数字。如果格式字符串中的数值 arg_name 按顺序为 0, 1, 2, ...,则可以省略所有(而不仅仅是部分),并且将按该顺序自动插入数字 0, 1, 2, ...。由于 arg_name 未用引号分隔,因此无法在格式字符串中指定任意字典键(例如,字符串 '10'':-]')。arg_name 可以后跟任意数量的索引或属性表达式。形式为 '.name' 的表达式使用 getattr() 选择命名属性,而形式为 '[index]' 的表达式使用 __getitem__() 执行索引查找。

3.1 版本发生变化: 可以省略 str.format() 的位置参数指定符,因此 '{} {}'.format(a, b) 等同于 '{0} {1}'.format(a, b)

3.4 版本发生变化: 可以省略 Formatter 的位置参数指定符。

一些简单的格式字符串示例

"First, thou shalt count to {0}"  # References first positional argument
"Bring me a {}"                   # Implicitly references the first positional argument
"From {} to {}"                   # Same as "From {0} to {1}"
"My quest is {name}"              # References keyword argument 'name'
"Weight in tons {0.weight}"       # 'weight' attribute of first positional arg
"Units destroyed: {players[0]}"   # First element of keyword argument 'players'.

conversion 字段在格式化之前强制进行类型转换。通常,格式化值的工作由值本身的 __format__() 方法完成。但是,在某些情况下,希望强制将类型格式化为字符串,从而覆盖其自己的格式化定义。通过在调用 __format__() 之前将值转换为字符串,可以绕过正常的格式化逻辑。

目前支持三种转换标志:'!s',它对值调用 str()'!r',它调用 repr();以及 '!a',它调用 ascii()

一些例子

"Harold's a clever {0!s}"        # Calls str() on the argument first
"Bring out the holy {name!r}"    # Calls repr() on the argument first
"More {!a}"                      # Calls ascii() on the argument first

format_spec 字段包含有关如何呈现值的规范,包括字段宽度、对齐方式、填充、小数精度等详细信息。每个值类型都可以定义自己的“格式化迷你语言”或对 format_spec 的解释。

大多数内置类型都支持一种常见的格式化迷你语言,这在下一节中描述。

format_spec 字段也可以在其内部包含嵌套替换字段。这些嵌套替换字段可以包含字段名、转换标志和格式规范,但不允许更深层次的嵌套。format_spec 中的替换字段在解释 format_spec 字符串之前进行替换。这允许动态指定值的格式。

有关示例,请参见 格式示例 部分。

格式规范迷你语言

“格式规范”用于格式字符串中包含的替换字段中,以定义单个值的呈现方式(参见 格式字符串语法f-字符串t-字符串)。它们也可以直接传递给内置的 format() 函数。每个可格式化类型都可以定义格式规范的解释方式。

大多数内置类型实现以下格式规范选项,尽管某些格式选项仅受数字类型支持。

一个普遍的约定是,空格式规范会产生与您对值调用 str() 相同的结果。非空格式规范通常会修改结果。

标准格式指定符 的一般形式是

format_spec:             [options][width_and_precision][type]
options:                 [[fill]align][sign]["z"]["#"]["0"]
fill:                    <any character>
align:                   "<" | ">" | "=" | "^"
sign:                    "+" | "-" | " "
width_and_precision:     [width_with_grouping][precision_with_grouping]
width_with_grouping:     [width][grouping]
precision_with_grouping: "." [precision][grouping] | "." grouping
width:                   digit+
precision:               digit+
grouping:                "," | "_"
type:                    "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g"
                         | "G" | "n" | "o" | "s" | "x" | "X" | "%"

如果指定了有效的 align 值,它前面可以有一个 fill 字符,该字符可以是任何字符,如果省略则默认为空格。在 格式化字符串字面值 或使用 str.format() 方法时,不能使用字面花括号(“{”或“}”)作为 fill 字符。但是,可以使用嵌套的替换字段插入花括号。此限制不影响 format() 函数。

各种对齐选项的含义如下

选项

含义

'<'

强制字段在可用空间内左对齐(这是大多数对象的默认设置)。

'>'

强制字段在可用空间内右对齐(这是数字的默认设置)。

'='

强制填充放在符号(如果有)之后,但数字之前。这用于以“+000000120”形式打印字段。此对齐选项仅对数字类型有效,不包括 complex。当“0”紧接字段宽度时,它成为数字的默认值。

'^'

强制字段在可用空间内居中对齐。

请注意,除非定义了最小字段宽度,否则字段宽度将始终与填充它的数据大小相同,因此在这种情况下对齐选项没有意义。

sign 选项仅对数字类型有效,可以是以下之一

选项

含义

'+'

表示正数和负数都应使用符号。

'-'

表示仅对负数使用符号(这是默认行为)。

空格

表示正数使用前导空格,负数使用负号。

'z' 选项会将负零浮点值在舍入到格式精度后强制转换为正零。此选项仅对浮点表示类型有效。

3.11 版本发生变化: 增加了 'z' 选项 (另请参见 PEP 682)。

'#' 选项导致对转换使用“备用形式”。备用形式对不同类型有不同的定义。此选项仅对整数、浮点数和复数类型有效。对于整数,当使用二进制、八进制或十六进制输出时,此选项会在输出值中添加相应的“0b”、“0o”、“0x”或“0X”前缀。对于浮点数和复数,备用形式导致转换结果始终包含小数点字符,即使后面没有数字。通常,只有在后面有数字时,这些转换的结果中才会出现小数点字符。此外,对于 'g''G' 转换,结果中不会删除末尾的零。

width 是一个十进制整数,定义了最小总字段宽度,包括任何前缀、分隔符和其他格式化字符。如果未指定,则字段宽度将由内容决定。

当未给出显式对齐时,在 width 字段前加上零 ('0') 字符可为数字类型(不包括 complex)启用符号感知零填充。这等同于 fill 字符为 '0'alignment 类型为 '='

3.10 版本发生变化: width 字段前加上 '0' 不再影响字符串的默认对齐方式。

precision 是一个十进制整数,表示对于表示类型 'f''F',小数点后应显示多少位数字;或者对于表示类型 'g''G',小数点前后应显示多少位数字。对于字符串表示类型,该字段表示最大字段大小 — 换句话说,将从字段内容中使用多少个字符。整数表示类型不允许使用 precision

widthprecision 字段后面的 grouping 选项分别指定了数字整数部分和小数部分的数字分组分隔符。它可以是以下之一

选项

含义

','

对于整数表示类型 'd' 和浮点表示类型(不包括 'n'),每 3 位插入一个逗号。对于其他表示类型,不支持此选项。

'_'

对于整数表示类型 'd' 和浮点表示类型(不包括 'n'),每 3 位插入一个下划线。对于整数表示类型 'b''o''x''X',每 4 位插入一个下划线。对于其他表示类型,不支持此选项。

对于区域设置感知分隔符,请改用 'n' 表示类型。

3.1 版本发生变化: 添加了 ',' 选项 (另请参见 PEP 378)。

3.6 版本发生变化: 添加了 '_' 选项 (另请参见 PEP 515)。

3.14 版本发生变化: 支持小数部分的 grouping 选项。

最后,type 决定了数据的呈现方式。

可用的字符串表示类型为

类型

含义

's'

字符串格式。这是字符串的默认类型,可以省略。

None

's' 相同。

可用的整数表示类型为

类型

含义

'b'

二进制格式。以 2 为基数输出数字。

'c'

字符。在打印前将整数转换为相应的 unicode 字符。

'd'

十进制整数。以 10 为基数输出数字。

'o'

八进制格式。以 8 为基数输出数字。

'x'

十六进制格式。以 16 为基数输出数字,使用小写字母表示大于 9 的数字。

'X'

十六进制格式。以 16 为基数输出数字,使用大写字母表示大于 9 的数字。如果指定了 '#',则前缀 '0x' 也会转换为大写 '0X'

'n'

数字。这与 'd' 相同,不同之处在于它使用当前区域设置插入适当的数字分组分隔符。

None

'd' 相同。

除了上述表示类型之外,整数还可以用下面列出的浮点表示类型进行格式化(除了 'n'None)。这样做时,float() 用于在格式化之前将整数转换为浮点数。

floatDecimal 值可用的表示类型为

类型

含义

'e'

科学计数法。对于给定精度 p,以科学计数法格式化数字,用字母“e”分隔系数和指数。系数在小数点前有一位数字,小数点后有 p 位数字,总共有 p + 1 位有效数字。如果未给出精度,对于 float,使用小数点后 6 位数字的精度,对于 Decimal,显示所有系数数字。如果 p=0,除非使用 # 选项,否则省略小数点。

'E'

科学计数法。与 'e' 相同,但使用大写 'E' 作为分隔符。

'f'

定点表示法。对于给定精度 p,将数字格式化为小数,小数点后恰好有 p 位数字。如果未给出精度,对于 float,使用小数点后 6 位数字的精度,对于 Decimal,使用足以显示所有系数数字的精度。如果 p=0,除非使用 # 选项,否则省略小数点。

'F'

定点表示法。与 'f' 相同,但将 nan 转换为 NAN,将 inf 转换为 INF

'g'

通用格式。对于给定精度 p >= 1,这会将数字四舍五入到 p 位有效数字,然后根据其大小将其格式化为定点格式或科学计数法。精度 0 被视为等同于精度 1

精确规则如下:假设以表示类型 'e' 和精度 p-1 格式化的结果的指数为 exp。那么,如果 m <= exp < p,其中 m 对于浮点数是 -4,对于 Decimals 是 -6,则数字以表示类型 'f' 和精度 p-1-exp 格式化。否则,数字以表示类型 'e' 和精度 p-1 格式化。在这两种情况下,如果有效数字中没有剩余的数字,并且除非使用 '#' 选项,否则将删除有效数字中不重要的尾随零以及小数点。

如果没有给出精度,对于 float,使用 6 位有效数字的精度。对于 Decimal,结果的系数由值的系数数字组成;对于绝对值小于 1e-6 的值和最小有效数字的位值大于 1 的值,使用科学计数法,否则使用定点计数法。

正负无穷大、正负零和 NaN 分别格式化为 inf-inf0-0nan,无论精度如何。

'G'

通用格式。与 'g' 相同,但如果数字太大则切换到 'E'。无穷大和 NaN 的表示也大写。

'n'

数字。这与 'g' 相同,不同之处在于它使用当前区域设置插入数字整数部分的适当数字分组分隔符。

'%'

百分比。将数字乘以 100 并以定点 ('f') 格式显示,后跟百分号。

None

对于 float,这类似于 'g' 类型,但当使用定点表示法格式化结果时,它始终包含小数点后至少一位数字,并且当 exp >= p - 1 时切换到科学计数法。当未指定精度时,后者将根据需要尽可能大以忠实地表示给定值。

对于 Decimal,这与 'g''G' 相同,具体取决于当前小数上下文的 context.capitals 值。

整体效果是匹配 str() 的输出,并由其他格式修饰符进行修改。

结果应正确舍入到小数点后给定精度 p 位数字。float 的舍入模式与内置的 round() 匹配。对于 Decimal,将使用当前 上下文 的舍入模式。

complex 的可用表示类型与 float 相同(不允许 '%')。复数的实部和虚部都根据指定的表示类型格式化为浮点数。它们由虚部的强制符号分隔,后者以 j 后缀结尾。如果缺少表示类型,结果将与 str() 的输出匹配(非零实部的复数也用括号括起来),可能会被其他格式修饰符更改。

格式示例

本节包含 str.format() 语法的示例以及与旧式 % 格式化的比较。

在大多数情况下,语法与旧式 % 格式化类似,增加了 {} 并使用 : 代替 %。例如,'%03.2f' 可以转换为 '{:03.2f}'

新的格式语法还支持新的和不同的选项,如下例所示。

按位置访问参数

>>> '{0}, {1}, {2}'.format('a', 'b', 'c')
'a, b, c'
>>> '{}, {}, {}'.format('a', 'b', 'c')  # 3.1+ only
'a, b, c'
>>> '{2}, {1}, {0}'.format('a', 'b', 'c')
'c, b, a'
>>> '{2}, {1}, {0}'.format(*'abc')      # unpacking argument sequence
'c, b, a'
>>> '{0}{1}{0}'.format('abra', 'cad')   # arguments' indices can be repeated
'abracadabra'

按名称访问参数

>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
'Coordinates: 37.24N, -115.81W'
>>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
>>> 'Coordinates: {latitude}, {longitude}'.format(**coord)
'Coordinates: 37.24N, -115.81W'

访问参数的属性

>>> c = 3-5j
>>> ('The complex number {0} is formed from the real part {0.real} '
...  'and the imaginary part {0.imag}.').format(c)
'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.'
>>> class Point:
...     def __init__(self, x, y):
...         self.x, self.y = x, y
...     def __str__(self):
...         return 'Point({self.x}, {self.y})'.format(self=self)
...
>>> str(Point(4, 2))
'Point(4, 2)'

访问参数项

>>> coord = (3, 5)
>>> 'X: {0[0]};  Y: {0[1]}'.format(coord)
'X: 3;  Y: 5'

替换 %s%r

>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"

对齐文本并指定宽度

>>> '{:<30}'.format('left aligned')
'left aligned                  '
>>> '{:>30}'.format('right aligned')
'                 right aligned'
>>> '{:^30}'.format('centered')
'           centered           '
>>> '{:*^30}'.format('centered')  # use '*' as a fill char
'***********centered***********'

替换 %+f%-f% f 并指定符号

>>> '{:+f}; {:+f}'.format(3.14, -3.14)  # show it always
'+3.140000; -3.140000'
>>> '{: f}; {: f}'.format(3.14, -3.14)  # show a space for positive numbers
' 3.140000; -3.140000'
>>> '{:-f}; {:-f}'.format(3.14, -3.14)  # show only the minus -- same as '{:f}; {:f}'
'3.140000; -3.140000'

替换 %x%o 并将值转换为不同的基数

>>> # format also supports binary numbers
>>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'

使用逗号或下划线作为数字分组分隔符

>>> '{:,}'.format(1234567890)
'1,234,567,890'
>>> '{:_}'.format(1234567890)
'1_234_567_890'
>>> '{:_b}'.format(1234567890)
'100_1001_1001_0110_0000_0010_1101_0010'
>>> '{:_x}'.format(1234567890)
'4996_02d2'
>>> '{:_}'.format(123456789.123456789)
'123_456_789.12345679'
>>> '{:.,}'.format(123456789.123456789)
'123456789.123,456,79'
>>> '{:,._}'.format(123456789.123456789)
'123,456,789.123_456_79'

表示百分比

>>> points = 19
>>> total = 22
>>> 'Correct answers: {:.2%}'.format(points/total)
'Correct answers: 86.36%'

使用特定类型格式

>>> import datetime
>>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)
>>> '{:%Y-%m-%d %H:%M:%S}'.format(d)
'2010-07-04 12:15:58'

嵌套参数和更复杂的示例

>>> for align, text in zip('<^>', ['left', 'center', 'right']):
...     '{0:{fill}{align}16}'.format(text, fill=align, align=align)
...
'left<<<<<<<<<<<<'
'^^^^^center^^^^^'
'>>>>>>>>>>>right'
>>>
>>> octets = [192, 168, 0, 1]
>>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets)
'C0A80001'
>>> int(_, 16)
3232235521
>>>
>>> width = 5
>>> for num in range(5,12):
...     for base in 'dXob':
...         print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')
...     print()
...
    5     5     5   101
    6     6     6   110
    7     7     7   111
    8     8    10  1000
    9     9    11  1001
   10     A    12  1010
   11     B    13  1011

模板字符串($-字符串)

备注

此处描述的功能是在 Python 2.4 中引入的;这是一种基于正则表达式的简单模板方法。它早于 str.format()格式化字符串字面值模板字符串字面值

它与在 Python 3.14 中引入的模板字符串字面值 (t-字符串) 无关。这些字符串字面值会评估为 string.templatelib.Template 对象,这些对象可以在 string.templatelib 模块中找到。

模板字符串提供了 PEP 292 中描述的更简单的字符串替换。模板字符串的一个主要用例是国际化 (i18n),因为在这种情况下,更简单的语法和功能使其比 Python 中其他内置字符串格式化工具更容易翻译。作为一个基于模板字符串实现 i18n 的库示例,请参见 flufl.i18n 包。

模板字符串支持基于 $ 的替换,使用以下规则

  • $$ 是一个转义符;它被替换为单个 $

  • $identifier 命名一个替换占位符,匹配映射键 "identifier"。默认情况下,"identifier" 仅限于以 _ 或 ASCII 字母开头且不区分大小写的 ASCII 字母数字字符串(包括下划线)。$ 字符后的第一个非标识符字符终止此占位符规范。

  • ${identifier} 等同于 $identifier。当有效标识符字符跟随占位符但不是占位符的一部分时,例如 "${noun}ification",它就是必需的。

字符串中 $ 的任何其他出现都将导致引发 ValueError

string 模块提供了一个实现这些规则的 Template 类。Template 的方法是

class string.Template(template)

构造函数接受一个参数,即模板字符串。

substitute(mapping={}, /, **kwds)

执行模板替换,返回一个新字符串。mapping 是任何类似字典的对象,其键与模板中的占位符匹配。或者,您可以提供关键字参数,其中关键字是占位符。当同时给出 mappingkwds 且存在重复时,kwds 中的占位符优先。

safe_substitute(mapping={}, /, **kwds)

substitute() 类似,但如果 mappingkwds 中缺少占位符,它不会引发 KeyError 异常,而是将原始占位符完整地保留在结果字符串中。此外,与 substitute() 不同,$ 的任何其他出现都只会返回 $,而不会引发 ValueError

尽管仍然可能发生其他异常,但此方法之所以被称为“安全”,是因为它总是尝试返回一个可用的字符串而不是引发异常。从另一个意义上说,safe_substitute() 可能并不安全,因为它会默默地忽略包含悬挂定界符、不匹配括号或不是有效 Python 标识符的占位符的格式错误的模板。

is_valid()

如果模板包含导致 substitute() 引发 ValueError 的无效占位符,则返回 False

在 3.11 版本中新增。

get_identifiers()

按首次出现的顺序返回模板中所有有效标识符的列表,忽略任何无效标识符。

在 3.11 版本中新增。

Template 实例还提供一个公共数据属性

template

这是传递给构造函数 template 参数的对象。通常,您不应更改它,但不会强制只读访问。

以下是使用 Template 的示例

>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'
>>> d = dict(who='tim')
>>> Template('Give $who $100').substitute(d)
Traceback (most recent call last):
...
ValueError: Invalid placeholder in string: line 1, col 11
>>> Template('$who likes $what').substitute(d)
Traceback (most recent call last):
...
KeyError: 'what'
>>> Template('$who likes $what').safe_substitute(d)
'tim likes $what'

高级用法:您可以从 Template 派生子类,以自定义占位符语法、定界符字符或用于解析模板字符串的整个正则表达式。为此,您可以重写这些类属性

  • delimiter – 这是一个字面字符串,描述了引入占位符的定界符。默认值为 $。请注意,这不应是正则表达式,因为实现会根据需要在此字符串上调用 re.escape()。另请注意,在类创建后您无法更改定界符(即必须在子类的类命名空间中设置不同的定界符)。

  • idpattern – 这是一个正则表达式,描述了非大括号占位符的模式。默认值为正则表达式 (?a:[_a-z][_a-z0-9]*)。如果给定了此值而 braceidpatternNone,则此模式也将应用于大括号占位符。

    备注

    由于默认 flagsre.IGNORECASE,因此模式 [a-z] 可以匹配一些非 ASCII 字符。这就是我们在此处使用本地 a 标志的原因。

    3.7 版本发生变化: braceidpattern 可用于定义大括号内部和外部使用的单独模式。

  • braceidpattern – 这类似于 idpattern,但描述了大括号占位符的模式。默认为 None,这意味着回退到 idpattern(即大括号内部和外部使用相同的模式)。如果给定,这允许您为带大括号和不带大括号的占位符定义不同的模式。

    在 3.7 版本加入。

  • flags – 在编译用于识别替换的正则表达式时将应用的正则表达式标志。默认值为 re.IGNORECASE。请注意,re.VERBOSE 将始终添加到标志中,因此自定义的 idpattern 必须遵循详细正则表达式的约定。

    在 3.2 版本加入。

或者,您可以通过覆盖类属性 pattern 来提供整个正则表达式模式。如果这样做,该值必须是一个正则表达式对象,包含四个命名捕获组。捕获组对应于上面给出的规则,以及无效占位符规则

  • escaped – 此组匹配转义序列,例如默认模式中的 $$

  • named – 此组匹配未加括号的占位符名称;它不应在捕获组中包含定界符。

  • braced – 此组匹配大括号括起来的占位符名称;它不应在捕获组中包含定界符或大括号。

  • invalid – 此组匹配任何其他定界符模式(通常是单个定界符),并且它应该出现在正则表达式的最后。

如果模式匹配模板而这些命名组之一不匹配,则此类的方​​法将引发 ValueError

辅助函数

string.capwords(s, sep=None)

使用 str.split() 将参数拆分为单词,使用 str.capitalize() 将每个单词首字母大写,然后使用 str.join() 连接大写后的单词。如果可选的第二个参数 sep 缺失或为 None,则连续的空白字符被替换为单个空格,并删除前导和尾随空白,否则 sep 用于拆分和连接单词。