文本文字处理之字符串的操作详解(10) – Python语言(必读进阶学习教程)(参考资料)
字符串常量
该模块中定义的常量是:
string.ascii_lettersascii_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()描述的方法 进行复杂变量替换和值格式化的能力。模块中的Formatter类string允许您使用与内置format()方法相同的实现来创建和自定义您自己的字符串格式化行为。
- class
string.Formatter - 该类
Formatter具有以下公共方法:format( format_string , *args , **kwargs )- 主要 API 方法。它采用格式字符串和任意一组位置和关键字参数。它只是一个调用
vformat().在 3.7 版更改:格式字符串参数现在是positional-only。
vformat( format_string , args , kwargs )- 此函数执行格式化的实际工作。在您想要传入预定义的参数字典的情况下,它作为一个单独的函数公开,而不是使用
*argsand**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)。默认版本采用中定义的形式的字符串,例如“0[name]”或“label.title”。 args和kwargs被传入到vformat(). 返回值used_key与 to 的key参数含义相同get_value()。
get_value(key, args , kwargs )- 检索给定的字段值。关键参数将是整数或字符串。如果是整数,则表示args中位置参数的索引;如果它是一个字符串,那么它表示kwargs中的一个命名参数。
args参数设置为 的位置参数列表 ,
vformat()而kwargs参数设置为关键字参数的字典。对于复合字段名称,这些函数仅针对字段名称的第一个组件调用;后续组件通过正常的属性和索引操作进行处理。
因此,例如,字段表达式“0.name”将导致
get_value()以0键参数调用。该属性将在返回后通过调用内置函数name进行查找。get_value()getattr()如果索引或关键字引用了不存在的项目,则 应该引发
IndexErrororKeyError
check_unused_args( used_args , args , kwargs )- 如果需要,实施检查未使用的参数。此函数的参数是格式字符串中实际引用的所有参数键的集合(位置参数的整数和命名参数的字符串),以及对传递给 vformat的args和kwargs的引用。可以从这些参数中计算出未使用的参数集。
check_unused_args()如果检查失败,则假定引发异常。
format_field(value, format_spec )format_field()简单地调用全局format()内置。提供该方法以便子类可以覆盖它。
convert_field(value,conversion)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 ::= identifier
element_index ::= digit+ | index_string
index_string ::= <any source character except "]"> +
conversion ::= "r" | "s" | "a"
format_spec ::= <described in the next section>
在不太正式的术语中,替换字段可以以field_name开头,该字段指定其值将被格式化并插入到输出中的对象,而不是替换字段。field_name后跟一个可选的 转换字段,前面有一个感叹号'!',还有一个format_spec,前面有一个冒号':'。这些指定替换值的非默认格式。
另请参阅格式规范迷你语言部分。
field_name本身以 arg_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
ormat_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’紧接在字段宽度之前时,它成为默认值。 '^'强制字段在可用空间内居中。
请注意,除非定义了最小字段宽度,否则字段宽度将始终与填充它的数据大小相同,因此在这种情况下,对齐选项没有意义。
该标志的选择是仅适用于数字类型,并且可以是下列之一:
选项 含义 '+'表示标志应该用于正数和负数。 '-'表示标志应仅用于负数(这是默认行为)。 空间 表示应在正数上使用前导空格,在负数上使用减号。
该'#'选项导致使用“替代形式”进行转换。替代形式对不同类型的定义不同。此选项仅对整数、浮点数、复数和小数类型有效。对于整数,当使用二进制、八进制或十六进制输出时,此选项将分别添加前缀'0b'、'0o'或 '0x'到输出值。对于浮点数、复数和小数,替代形式会导致转换结果始终包含小数点字符,即使它后面没有数字。通常,小数点字符仅在其后有数字时才会出现在这些转换的结果中。此外,对于'g'和'G' 转换,尾随零不会从结果中删除。
该','选项表示使用逗号作为千位分隔符。对于区域设置感知分隔符,请改用'n'整数表示类型。
在 3.1 版更改:添加了','选项。
该'_'选项表示使用下划线作为浮点表示类型和整数表示类型的千位分隔符'd'。对于整数表示类型'b'、 'o'、'x'和'X',将每 4 位插入下划线。对于其他演示文稿类型,指定此选项是错误的。
在 3.6 版更改:添加了'_'选项。
width是定义最小总字段宽度的十进制整数,包括任何前缀、分隔符和其他格式字符。如果未指定,则字段宽度将由内容决定。
当没有给出明确的对齐方式时,在宽度字段前加一个零 ( '0') 字符会启用数字类型的符号感知零填充。这等效于对齐类型为的填充 字符。'0''='
精度是一个十进制数,表示在使用'f'and格式的浮点值的小数点后应显示多少位 'F',或在使用'g'or格式的浮点值的小数点前后显示多少位'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 >= 1p精确的规则如下:假设使用表示类型
'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()语法示例以及与旧%格式的比较。
在大多数情况下,语法类似于旧的%– 格式,只是添加了{}and 并用:used 代替%. 例如,'%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
模板字符串提供更简单的字符串替换。模板字符串的主要用例是国际化(i18n),因为在该上下文中,更简单的语法和功能使其比Python中的其他内置字符串格式化工具更容易翻译。作为基于i18n模板字符串构建的库的示例,请参阅 flufl.i18n软件包。
模板字符串支持$基于替换,使用以下规则:
$$是逃避; 它被替换为单个$。$identifier命名匹配映射键的替换占位符"identifier"。默认情况下,"identifier"仅限于以下划线或ASCII字母开头的任何不区分大小写的ASCII字母数字字符串(包括下划线)。字符后面的第一个非标识符$字符终止此占位符规范。${identifier}相当于$identifier。当有效标识符字符跟随占位符但不是占位符的一部分时,例如,这是必需的"${noun}ification"。
$字符串中的任何其他外观都会导致ValueError 被提升。
该string模块提供了一个Template实现这些规则的类。方法Template是:
- class
string.templateTemplate() - 构造函数采用单个参数,即模板字符串。
mappingsubstitute(**kwds,)- 执行模板替换,返回一个新字符串。 mapping是任何类似字典的对象,其键与模板中的占位符匹配。或者,您可以提供关键字参数,其中关键字是占位符。当给出映射和kwds并且存在重复时,来自kwds的占位符优先。
mappingsafe_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 – 此组匹配任何其他分隔符模式(通常是单个分隔符),它应该出现在正则表达式的最后。