6.1. string - 常用字符串操作

源代码: Lib/string.py

6.1.1.字符串常量

在这个模块中定义的常量如下:

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

被定义为printable的ASCII 字符集合而成的字符串,这是一个包含了 位数, ascii字符, 标点符号, 和空格.的组合

string.whitespace

包含所有ASCII中可当作空白的字符集合而成的字符串。这包括字符间的空间、 tab、 换行符、 return、 换页符和垂直制表符(vertical tab)。

6.1.2.自定义字符串格式

内建的string类通过format() 提供了处理复杂变量替换以及值格式化的能力 ,参见PEP 3101.string 模块中的Formatter类允许您创建和自定义您自己的字符串格式行为作为内置 format() 方法使用相同的实现。

class string.Formatter

Formatter 类具有下列的公共方法:

format(format_string, *args, **kwargs)

主要的 API 方法。该方法需要一个格式化字符串(format string)和任意一组由位置和关键字组成的参数。这个方法只是 vformat()方法的一个封装而已.

3.5 版弃用︰将格式字符串作为关键字参数 format_string 传递已被弃用。

vformat(format_string, args, kwargs)

此函数负责实际格式化的工作。如果你想传递一个预定义的参数字典,而不是使用*args**kwargsvformat()执行将格式字符串分解为字符数据和替换字段的工作。它调用下面描述的各种方法。

此外,Formatter定义了许多要由子类替换的方法:

parse(format_string)

对 format_string 进行循环,并返回可迭代的元组 (literal_text字段名format_spec转换)。这由vformat()使用以将字符串拆分为文本文本或替换字段。

中元组的值在概念上表示其后更换单个字段的文本范围。如果没有文本 (有可能发生,如果两个替换领域相继发生),那么literal_text将一个零长度的字符串。如果没有替换字段,则field_nameformat_spec转换的值将为None

get_field(field_name, args, kwargs)

给定由parse()(见上文)返回的field_name,将其转换为要格式化的对象。返回一个元组 (obj,used_key)。默认版本采用 PEP 3101中定义的格式的字符串,例如“0 [name]”或“label.title”。argskwargs传递到vformat()返回值used_key参数和get_value()具有相同的含义。

get_value(key, args, kwargs)

检索一个给定的字段值。Key 参数可以是一个整数或一个字符串。如果它是一个整数,它表示在 args; 位置参数的索引位置;如果它是一个字符串,那么它表示在 kwags 里的一个命名的参数。

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

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

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

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

check_unused_args(used_args, args, kwargs)

执行检查未使用的参数,如果需要。对此函数的参数是在格式字符串 (整数位置参数) 和命名参数的字符串,并且对参数调用传递给 vformat 的引用实际上提到的所有参数键的集合。从这些参数,可以计算的未使用的参数集。check_unused_args()假定在检查失败时引发异常。

format_field(value, format_spec)

format_field()只是调用内置的全局format()该方法提供,以便子类可以重写它。

convert_field(value, conversion)

转换给定转换类型的值(由get_field()返回)(如parse()方法返回的元组)。默认版本理解的 ' (str),'r' (代表) 和 'a' (ascii) 类型转换。

6.1.3.格式字符串语法

str.format()方法和Formatter 类在格式化字符串时使用的是相同的语法(Formatter的子类能够定义它自己的格式字符串的语法)。

格式字符串包含了被大括号括起来的“替代字段” {}所有括号外的内容均被视作文本,不做任何改变直接按原样输出。如果你需要在文本中写大括号(此大括号不是语法中使用的,是要输出的文本中本来就有的),要用两个大括号括起来。例如:{{ and }}.

替换字段的语法如下所示:

 replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" field_name  ::= arg_name ("." attribute_name | "[" element_index "]")* arg_name  ::= [identifier | integer] attribute_name  ::= identifier element_index  ::= integer | index_string index_string  ::= <any source character except "]"> + conversion  ::= "r" | "s" | "a" format_spec  ::= <described in the next section> 

用不正式的术语来说,替换字段可以用field_name开始,它指定值要进行格式化并插入到的输出以代替替换字段的对象。field_name之后可以跟随一个以感叹号'!'开始的conversion字段,和一个以':'开始的format_spec它们指定替换值的非默认的格式。

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

field_name的参数arg_name要么是一个数字,要么是一个键。如果它是一个数字,它是指一个位置参数,而如果它是一个键,它指命名的关键字参数。如果序列字符串中的数字参数arg_names是像0,1,2,...这样的序列,那它们可以全部省略 (不只是部分),并且此序列0,1,2,......将按那个顺序被自动插入。因为arg_name不是引号分隔的,所以在格式化字符串中不可能指定任意字典键(例如,字符串'10'':-]')。arg_name的后面可以跟随任意数量的索引或属性表达式。形式'.name'的表达式使用getattr()选择命名属性,而形式'[index]'使用__getitem__()进行索引查找。

在版本3.1中更改:位置参数说明符可以省略,因此'{} {}' 等同于'{0} {1}'

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

"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字符串被解释。这将允许动态地指定的值的格式。

有关示例,请参阅Format examples部分。

6.1.3.1.格式规范迷你语言

"格式化规范"中用于替换字段包含在一个格式字符串来定义如何个别值给出了使用 (请参见 字符串格式化语法)。他们还可以通过直接向内置 format () 函数。每个可格式化的类型须定义格式化规范是如何被解释。

大多数内置类型都实现了以下的格式描述选项中,虽然一些格式选项只支持数值类型。

一般的约定是,空格式字符串("")产生的结果与在该值上调用str()的结果相同。非空格式字符串通常会修改结果。

标准格式说明符的一般形式为:

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

如果指定了一个无效的对齐值,它可以以可以是任何字符和空间,如果省略默认填充字符开头。当使用str.format()方法时无法发使用花括号 (“{” 或者 “}”) 当作 填充字符 但是,可以插入带有嵌套替换字段的大括号。此限制不会影响format()函数。

不同的对齐方式选项的含义如下所示:

Option Meaning
'<' Forces the field to be left-aligned within the available space (this is the default for most objects).
'>' Forces the field to be right-aligned within the available space (this is the default for numbers).
'=' Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form ‘+000000120’. This alignment option is only valid for numeric types. It becomes the default when ‘0’ immediately precedes the field width.
'^' Forces the field to be centered within the available space.

请注意除非定义最小字段宽度,则字段宽度总是将大小相同的数据,来填满它,以便对齐选项已经没有任何意义在这种情况下。

符号选项只是有效的数字类型,并且可以将下列操作之一:

Option Meaning
'+' indicates that a sign should be used for both positive as well as negative numbers.
'-' indicates that a sign should be used only for negative numbers (this is the default behavior).
space indicates that a leading space should be used on positive numbers, and a minus sign on negative numbers.

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

','选项指示对于千位分隔符使用逗号。对于区域设置感知分隔符,请改用'n'整数呈现类型。

在版本3.1中已更改:添加了','选项(另请参阅 PEP 378)。

宽度是定义最小字段宽度的十进制整数。如果未指定,那么将由内容决定字段宽度。

当未给出显式对齐时,通过零('0')字符在width字段前面启用数字类型的符号感知填零。这等同于'='类型的对齐类型的'0'填充字符。

The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating point value formatted with 'f' and 'F', or before and after the decimal point for a floating point value formatted with 'g' or 'G'. 对于非数字类型字段指示的最大字段大小 — — 换句话说,将从字段内容使用多少个字符。精度是不允许使用整数值。

最后,类型确定数据的显示方式。

可用字符串演示文稿类型有:

Type Meaning
's' String format. This is the default type for strings and may be omitted.
None The same as 's'.

可用整数演示文稿类型有:

Type Meaning
'b' Binary format. Outputs the number in base 2.
'c' Character. Converts the integer to the corresponding unicode character before printing.
'd' Decimal Integer. Outputs the number in base 10.
'o' Octal format. Outputs the number in base 8.
'x' Hex format. Outputs the number in base 16, using lower- case letters for the digits above 9.
'X' Hex format. Outputs the number in base 16, using upper- case letters for the digits above 9.
'n' Number. This is the same as 'd', except that it uses the current locale setting to insert the appropriate number separator characters.
None The same as 'd'.

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

可用的演示文稿类型为浮点数和小数的值有:

Type Meaning
'e' Exponent notation. Prints the number in scientific notation using the letter ‘e’ to indicate the exponent. The default precision is 6.
'E' Exponent notation. Same as 'e' except it uses an upper case ‘E’ as the separator character.
'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
'F' Fixed point. Same as 'f', but converts nan to NAN and inf to INF.
'g'

General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude.

The precise rules are as follows: suppose that the result formatted with presentation type 'e' and precision p-1 would have exponent exp. Then if -4 <= exp < p, the number is formatted with presentation type 'f' and precision p-1-exp. Otherwise, the number is formatted with presentation type 'e' and precision p-1. In both cases insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it.

Positive and negative infinity, positive and negative zero, and nans, are formatted as inf, -inf, 0, -0 and nan respectively, regardless of the precision.

A precision of 0 is treated as equivalent to a precision of 1. The default precision is 6.

'G' General format. Same as 'g' except switches to 'E' if the number gets too large. The representations of infinity and NaN are uppercased, too.
'n' Number. This is the same as 'g', except that it uses the current locale setting to insert the appropriate number separator characters.
'%' Percentage. Multiplies the number by 100 and displays in fixed ('f') format, followed by a percent sign.
None Similar to 'g', except that fixed-point notation, when used, has at least one digit past the decimal point. The default precision is as high as needed to represent the particular value. The overall effect is to match the output of str() as altered by the other format modifiers.

6.1.3.2.格式示例

本节包含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'

表示百分比:

>>> 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

6.1.4.模板字符串

模板提供了更简单的字符串替换,如 PEP 292中所述。除了正常的基于%的替换,模板使用支持基于$以下规则的替换:

  • $$是一个转义符;它被替换为单个$
  • $identifier命名与"identifier"的映射键匹配的替换占位符。默认情况下,"identifier"限于以下划线或ASCII字母开头的任何不区分大小写的ASCII字母数字字符串(包括下划线)。$字符后面的第一个非标识符字符终止此占位符规范。
  • ${identifier}等效于$identifier当有效的标识符字符位于占位符之后但不是占位符的一部分时,例如"${noun}ification"时,此属性是必需的。

在字符串中任何其他外观$将导致ValueError被引发。

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

class string.Template(template)

构造函数采用单个参数即模板字符串。

substitute(mapping, **kwds)

执行模板替换,返回一个新字符串。映射是任何类似于字典对象与键匹配的模板中的占位符。或者,您可以提供关键字参数,这些关键字在哪里的占位符。当给定映射kwds并且存在重复时,来自kwds的占位符优先。

safe_substitute(mapping, **kwds)

substitute(),除了如果映射kwds缺少占位符,而不是引发KeyError异常,原始占位符将出现在生成的字符串中。此外,与substitute()不同,$的任何其他外观将简单地返回$,而不是提高ValueError

虽然其他例外情况仍然可能发生,但这种方法称为"安全"因为替换总是试图返回一个可用的字符串,而不是引发异常。在另一种意义上,safe_substitute()可能是安全之外的任何东西,因为它会默默地忽略包含悬挂分隔符,不匹配的大括号或不是有效的Python标识符的占位符的畸形模板。

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-z][_a-z0-9]*

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

    版本3.2中的新功能。

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

  • 转义 - 此组与转义序列匹配,例如$$
  • named - 此组与未支持的占位符名称匹配;它不应该在捕获组中包括分隔符。
  • braced - 此群组与括号括起的占位符名称匹配;它不应该在捕获组中包括分隔符或大括号。
  • invalid - 此组与任何其他分隔符模式(通常为单个分隔符)匹配,它应该显示在正则表达式的最后。

6.1.5.辅助函数

string.capwords(s, sep=None)

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