Python Module之string - 文本常量和模板

模块目的:包含一些处理文本的常量和类

string模块可以追溯到Python的最初版本。该模块原先的许多方法都被移植到了str对象中,但是string模块依然保留了一些比较有用的常量和类,以便和str对象搭配使用。本篇讨论将着重关注string模块。


方法

capwords()方法可以将一个字符串中的所有单词转换成其首字母大写(其余字母小写)的形式。

# string_capwords.py
import string

s = 'The quick brown fox jumped over the lazy dog.'

print(s)
print(string.capwords(s))

转换的结果和我们先用split()分割,让每个分割后的单词首字母大写,再调用join()方法合并单词的结果是一致的。

$ python3 string_capwords.py

The quick brown fox jumped over the lazy dog.
The Quick Brown Fox Jumped Over The Lazy Dog.

注:其实str对象本身有一个title()方法,与此效果是一致的。


模板

字符串模板作为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))

在前两个例子中,标识符$%需要重复两次来转义。而对于format语法,左括号{和右括号}也都需要重复两次来转义。

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

使用Template和其他字符串格式化方法的一个重要区别是我们无需考虑参数的类型。参数值会自动转换成字符串类型,然后被插入结果字符串中。这里也没有额外的格式化选项,比如,我们没有办法去控制一个浮点型参数值的精度。

但是,一个额外的好处是,我们可以使用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))

在这个例子中,参数值字典中没有missing这个值,所以substitute()方法会引发一个KeyError异常。而safe_substitute()方法并不会引发异常,而是会捕获它, 并将没有匹配的参数表达式留在结果字符串中。

$ python3 string_template_missing.py

ERROR: 'missing'
safe_substitute(): foo is here but $missing is not provided

高级模板

string.Template的默认语法规则可以通过调整它所使用的寻找变量名字的正则表达式来改变。一个简单的可以实现这个效果的方法是,改变delimiteridpattern这两个类属性。

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

在这个例子中,我们通过继承string.Template改变了置换规则,标识符变成了%而不是$,并且变量名字必须在中间某个地方包含下划线_%notunderscored变量没有被替换,因为该变量没有包含下划线_

$ python3 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属性来得到。

\$(?:
  (?P<escaped>\$) |                # two delimiters
  (?P<named>[_a-z][_a-z0-9]*)    | # identifier
  {(?P<braced>[_a-z][_a-z0-9]*)} | # braced identifier
  (?P<invalid>)                    # ill-formed delimiter exprs
)

下述例子定义了一个新的正则模式,从而定义了一个新的Template,该Template使用{{var}}来作为变量匹配的语法规则。

# string_template_newsyntax.py
import re
import string


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


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

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

注意,namedbraced命名组需要都提供,即使它们是一样的。运行上述样例得到下面的输出:

$ python3 string_template_newsyntax.py

MATCHES: [('{{', '', '', ''), ('', 'var', '', '')]
SUBSTITUTED:
{{
replacement

Formatter类

Formatterstr对象的format()方法类似。在多数情况下,format()方法更为简便,但是Formatter类提供了一个建立子类的途径。


常量

string模块包含了许多了常量和数字字符集合。

# 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编码格式文本的流行,这些常量的作用也变得有限了。

$ python3 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'

原文点这里

参考:
1.string模块的官方文档
2.String方法 - str对象的方法
3.PEP 292 - Simpler String Substitutions
4.格式化字符串语法规则 - 使用Formatterstr.format()的规范

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值