文本文字处理之字符串的操作详解(10)Python语言(必读进阶学习教程)(参考资料)
字符串常量
此模块中定义的常量为:
string.
ascii_letters
- 下面描述的
ascii_lowercase
和ascii_uppercase
常量的串联。此值不依赖于语言环境。
string.
ascii_lowercase
- 小写字母
'abcdefghijklmnopqrstuvwxyz'
。此值不依赖于语言环境,不会更改。
string.
ascii_uppercase
- 大写字母
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
。此值不依赖于语言环境,不会更改。
string.
digits
- 字符串
'0123456789'
。
string.
hexdigits
- 字符串
'0123456789abcdefABCDEF'
。
string.
octdigits
- 字符串
'01234567'
。
string.
punctuation
- ASCII字符的字符串,在
C
语言环境中被视为标点字符。
string.
printable
- 被视为可打印的ASCII字符串。这是一个组合
digits
,ascii_letters
,punctuation
,和whitespace
。
string.
whitespace
- 包含所有被视为空格的ASCII字符的字符串。这包括字符空间,制表符,换行符,返回页面,换页符和垂直选项卡。
自定义字符串格式
内置字符串类提供了通过以下format()
方法 执行复杂变量替换和值格式化的功能PEP 3101。模块中的Formatter
类string
允许您使用与内置format()
方法相同的实现来创建和自定义您自己的字符串格式化行为。
- 类
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_name,format_spec和conversion的值 将为
None
。
get_field
(field_name,args,kwargs )- 给定field_name返回
parse()
(参见上文),将其转换为要格式化的对象。返回一个元组(obj,used_key)。默认版本采用在中定义的表单的字符串PEP 3101,例如“0 [name]”或“label.title”。 args和kwargs如同传入vformat()
。返回值 used_key与 key参数的含义相同get_value()
。
get_value
(键,args,kwargs )- 检索给定的字段值。的关键参数将是一个整数或字符串。如果是整数,则表示args中位置参数的索引; 如果它是一个字符串,那么它代表kwargs中的命名参数。
该ARGS参数设置的位置参数列表
vformat()
,以及kwargs参数设置为关键字参数的字典。对于复合字段名称,仅为字段名称的第一个组件调用这些函数; 后续组件通过常规属性和索引操作来处理。
因此,例如,字段表达式“0.name”将导致
get_value()
使用键参数0 调用。通过调用内置函数返回name
后将查找该属性。get_value()
getattr()
如果索引或关键字引用了不存在的项,则应引发
IndexError
或者KeyError
引发该项 。
check_unused_args
(used_args,args,kwargs )- 如果需要,实现检查未使用的参数。此函数的参数是格式字符串中实际引用的所有参数键的集合(位置参数的整数和命名参数的字符串),以及对传递给vformat 的args和kwargs的引用。可以从这些参数计算未使用的args集。
check_unused_args()
如果检查失败,则假定引发异常。
format_field
(value,format_spec )format_field()
只需调用全局format()
内置函数。提供该方法以便子类可以覆盖它。
convert_field
(价值,转换)get_field()
给定转换类型转换值(返回者)(如parse()
方法返回的元组)。默认版本理解’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 :: = element_index :: = + | index_string :: = <除“”“> + conversion :: =”r“| 之外的任何源字符 “s”| “a” format_spec :: = <在下一节中描述> identifier digitindex_string
在不太正式的术语中,替换字段可以以field_name开头,该字段指定要将其值格式化并插入输出而不是替换字段的对象。所述FIELD_NAME任选地跟随一个 转换字段,它是由前面带有感叹号'!'
,和一个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中更改:可以省略位置参数说明符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'.
的转换场引起格式化之前,类型强制。通常,格式化值的工作是通过__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()
函数。每种格式表类型可以定义如何解释格式规范。
尽管某些格式选项仅受数字类型支持,但大多数内置类型都会为格式规范实现以下选项。
一般惯例是,空格式字符串(""
)产生的结果与调用str()
该值时的结果相同。非空格式字符串通常会修改结果。
标准格式说明符的一般形式是:
format_spec :: = [[ fill] align] [ sign] [#] [0] [ width] [ grouping_option] [。precision] [ type] fill :: = <任何字符> align :: =“<”| “>”| “=”| “^” 符号 :: =“+”| “ - ”| “” width :: = digit+ grouping_option :: =“_”| “,” precision :: = digit+ type :: =“b”| “c”| “d”| “e”| “E”| “f”| “F”| “g”| “G”| “n”| “o”| “s”| “x”| “
如果指定了有效的对齐值,则可以在其前面加上 可以是任何字符的填充字符,如果省略则默认为空格。无法使用文字大括号(“ {
”或“ }
”)作为格式化字符串文字中的填充字符或使用该 方法时。但是,可以插入带有嵌套替换字段的大括号。此限制不会影响功能。str.format()
format()
各种对齐选项的含义如下:
选项 含义 '<'
强制字段在可用空间内左对齐(这是大多数对象的默认值)。 '>'
强制字段在可用空间内右对齐(这是数字的默认值)。 '='
强制将填充放置在符号(如果有)之后但在数字之前。这用于以“+000000120”形式打印字段。此对齐选项仅对数字类型有效。当’0’紧接在字段宽度之前时,它成为默认值。 '^'
强制字段在可用空间内居中。
请注意,除非定义了最小字段宽度,否则字段宽度将始终与填充它的数据大小相同,因此在这种情况下,对齐选项没有意义。
该标志的选择是仅适用于数字类型,并且可以是下列之一:
选项 含义 '+'
表示标志应该用于正数和负数。 '-'
表示标志应仅用于负数(这是默认行为)。 空间 表示应在正数上使用前导空格,在负数上使用减号。
该'#'
选项使“替代形式”用于转换。对于不同类型,替代形式的定义不同。此选项仅对integer,float,complex和Decimal类型有效。为整数,当二进制,八进制或十六进制输出时,此选项添加前缀相应'0b'
,'0o'
或 '0x'
该输出值。对于浮点数,复数和十进制,备用形式会导致转换结果始终包含小数点字符,即使后面没有数字也是如此。通常,只有在跟随数字的情况下,这些转换的结果中才会出现小数点字符。此外,对于 转换'g'
和'G'
转换,不会从结果中删除尾随零。
该','
选项表示使用逗号表示千位分隔符。对于区域设置感知分隔符,请改用'n'
整数表示类型。
版本3.1中已更改:添加了','
选项(另请参阅PEP 378)。
该'_'
选项表示对数字分隔符使用下划线表示浮点表示类型和整数表示类型'd'
。对于整数呈现类型'b'
,'o'
,'x'
,和'X'
,下划线将每4位插入。对于其他演示文稿类型,指定此选项是错误的。
在版本3.6中更改:添加了'_'
选项(另请参阅PEP 515)。
width是定义最小字段宽度的十进制整数。如果未指定,则字段宽度将由内容确定。
如果没有给出明确的对齐,则在width('0'
)字符前面的width字段可以为数字类型启用符号识别的零填充。这等同于一个填充 的字符'0'
与对准的类型'='
。
的精度是指示多少位数应的小数点格式化与浮点值之后显示的十进制数 'f'
和'F'
,或之前和小数点用于与格式化的浮点值之后'g'
或'G'
。对于非数字类型,该字段表示最大字段大小 – 换句话说,将使用字段内容中将使用的字符数。的精度是不允许的整数值。
最后,类型决定了数据的呈现方式。
可用的字符串表示类型是:
类型 含义 's'
字符串格式。这是字符串的默认类型,可以省略。 没有 同样的 's'
。
可用的整数表示类型是:
类型 含义 'b'
二进制格式。输出基数2中的数字。 'c'
字符。在打印之前将整数转换为相应的unicode字符。 'd'
十进制整数。输出基数为10的数字。 'o'
八进制格式。输出基数为8的数字。 'x'
十六进制格式 输出基数为16的数字,使用小写字母表示9以上的数字。 'X'
十六进制格式 输出基数16中的数字,使用大写字母表示9以上的数字。 'n'
数。 'd'
除了它使用当前语言环境设置插入适当的数字分隔符之外,它是相同的。没有 同样的 'd'
。
除了上面的表示类型之外,还可以使用下面列出的浮点表示类型(除了'n'
和None
)来格式化整数 。这样做时,float()
用于在格式化之前将整数转换为浮点数。
浮点和小数值的可用表示类型是:
类型 含义 'e'
指数表示法。使用字母“e”以科学记数法打印数字以表示指数。默认精度为 6
。'E'
指数表示法。与 'e'
使用大写字母“E”作为分隔符的情况相同。'f'
定点表示法。将数字显示为定点数。默认精度为 6
。'F'
定点表示法。同 'f'
,但转换nan
到NAN
和inf
到INF
。'g'
一般格式。对于给定的精度,将数字舍入为有效数字,然后根据其大小以定点格式或科学记数法格式化结果。
p >= 1
p
精确的规则如下:假设使用表示类型
'e'
和精度格式化的结果p-1
将具有指数exp
。然后,如果,数字格式化为演示文稿类型和精度 。否则,使用表示类型和精度格式化数字。在这两种情况下,从有效数字中删除无关紧要的尾随零,如果后面没有剩余数字,则也会删除小数点。-4 <= exp < p
'f'
p-1-exp
'e'
p-1
正和负无穷大,正的和负的零,和NaN,被格式化为
inf
,-inf
,0
,-0
和nan
的分别,而不管精度。精度
0
被视为等于精度1
。默认精度为6
。'G'
一般格式。与 'g'
切换到相同,'E'
如果数字太大。无穷大和NaN的表示也是大写的。'n'
数。 'g'
除了它使用当前语言环境设置插入适当的数字分隔符之外,它是相同的。'%'
百分比。将数字乘以100并以固定( 'f'
)格式显示,后跟百分号。没有 类似于 'g'
,除了定点表示法,使用时,至少有一位数字超过小数点。默认精度与表示特定值所需的一样高。总体效果是匹配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'
表达百分比:
>>> >>> 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
模板字符串
模板字符串提供更简单的字符串替换,如中所述 PEP 292。模板字符串的主要用例是国际化(i18n),因为在该上下文中,更简单的语法和功能使其比Python中的其他内置字符串格式化工具更容易翻译。作为基于i18n模板字符串构建的库的示例,请参阅 flufl.i18n软件包。
模板字符串支持$
基于替换,使用以下规则:
$$
是逃避; 它被替换为单个$
。$identifier
命名匹配映射键的替换占位符"identifier"
。默认情况下,"identifier"
仅限于以下划线或ASCII字母开头的任何不区分大小写的ASCII字母数字字符串(包括下划线)。字符后面的第一个非标识符$
字符终止此占位符规范。${identifier}
相当于$identifier
。当有效标识符字符跟随占位符但不是占位符的一部分时,例如,这是必需的"${noun}ification"
。
$
字符串中的任何其他外观都会导致ValueError
被提升。
该string
模块提供了一个Template
实现这些规则的类。方法Template
是:
- class
string.
Template
(模板) - 构造函数采用单个参数,即模板字符串。
substitute
(映射,** kwds )- 执行模板替换,返回一个新字符串。 mapping是任何类似字典的对象,其键与模板中的占位符匹配。或者,您可以提供关键字参数,其中关键字是占位符。当给出映射和kwds并且存在重复时,来自kwds的占位符优先。
safe_substitute
(映射,** 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:[_a-z][_a-z0-9]*)
。如果给出并且braceidpattern,则None
此模式也将适用于支撑占位符。注意
由于默认标志是
re.IGNORECASE
,因此模式[a-z]
可以与某些非ASCII字符匹配。这就是我们在a
这里使用本地旗帜的原因。版本3.7中更改:braceidpattern可用于定义大括号内外使用的单独模式。
-
braceidpattern – 这类似于idpattern,但描述了支撑占位符的模式。默认值
None
意味着回 退到idpattern(即在括号内部和外部使用相同的模式)。如果给定,则允许您为支撑和非支撑占位符定义不同的模式。版本3.7中的新功能。
-
flags – 编译用于识别替换的正则表达式时将应用的正则表达式标志。默认值为
re.IGNORECASE
。请注意,re.VERBOSE
将始终将其添加到标志中,因此自定义idpattern必须遵循详细正则表达式的约定。版本3.2中的新功能。
或者,您可以通过覆盖类属性模式来提供整个正则表达式模式。如果执行此操作,则该值必须是具有四个命名捕获组的正则表达式对象。捕获组对应于上面给出的规则以及无效的占位符规则:
- 转义 – 此组匹配转义序列,例如
$$
,默认模式。 - named – 此组与未支撑的占位符名称匹配; 它不应该包括捕获组中的分隔符。
- braced – 此组匹配括号括号占位符名称; 它不应该包括捕获组中的分隔符或大括号。
- invalid – 此组匹配任何其他分隔符模式(通常是单个分隔符),它应该出现在正则表达式的最后。