每週一個 Python 模組 | string

yongxinz發表於2019-03-03

專欄地址:每週一個 Python 模組

目的:包含用於處理文字的常量和類。

string 模組可以追溯到最早的 Python 版本。先前在此模組中實現的許多功能已移至 str 物件方法。string 模組保留了幾個有用的常量和類來處理 str 物件。

函式 capwords()

直接看下面的事例:

import string

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

print(s)    # The quick brown fox jumped over the lazy dog.
print(string.capwords(s))   # The Quick Brown Fox Jumped Over The Lazy Dog.
複製程式碼

模板

字串模板作為 PEP 292 一部分新增,旨在替代內建插值語法。通過 string.Template 插值,在名稱前加上 $(例如,$var)來標識變數。或者,如果需要將它們從周圍的文字中設定出來,它們也可以用花括號包裹(例如:${var})。

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

# output
# TEMPLATE:
# Variable        : foo
# Escape          : $
# Variable in text: fooiable
# 
# INTERPOLATION:
# Variable        : foo
# Escape          : %
# Variable in text: fooiable
# 
# FORMAT:
# Variable        : foo
# Escape          : {}
# Variable in text: fooiable
複製程式碼

在前兩種情況下,觸發字元($或%)通過重複兩次來轉義。對於語法格式,{} 都需要通過重複它們進行轉義。

模板和字串插值或格式化之間的一個關鍵區別是不考慮引數型別。這些值將轉換為字串,並將字串插入到結果中,沒有可用的格式選項。例如,無法控制用於表示浮點值的位數。

有一個好處是,如果並非模板所需的所有值都作為引數提供,則使用 safe_substitute() 方法可以避免異常。

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

# output
# ERROR: `missing`
# safe_substitute(): foo is here but $missing is not provided
複製程式碼

由於字典中沒有 missing 值,引發了一個 KeyErrorsafe_substitute() 捕獲它並在文字中單獨保留變數表示式。

高階模板

可以通過調整用於在模板主體中查詢變數名稱的正規表示式模式來更改預設語法。一種簡單的方法是更改 delimiteridpattern 類屬性。

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

# output
# Modified ID pattern:
# 
#   Delimiter : %
#   Replaced  : replaced
#   Ignored   : %notunderscored
複製程式碼

在此示例中,替換規則已更改,以分隔符%代替,而變數名必須在中間某處包含下劃線。該模式 %notunderscored 不會被任何內容替換,因為它不包含下劃線字元。

對於更復雜的更改,可以覆蓋 pattern 屬性並定義全新的正規表示式。提供的模式必須包含四個命名組,用於捕獲轉義分隔符,命名變數,變數名稱的支撐版本以及無效分隔符模式。

import string

t = string.Template(`$var`)
print(t.pattern.pattern)

# output
# $(?:
#   (?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
# )
複製程式碼

t.pattern 是一個已編譯的正規表示式,但原始字串可通過其 pattern 屬性獲得。

此示例使用 {{var}} 作為變數語法定義用於建立新型別模板的新模式。

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

# output
# MATCHES: [(`{{`, ``, ``, ``), (``, `var`, ``, ``)]
# SUBSTITUTED:
# {{
# replacement
複製程式碼

無論是 namedbraced 模式必須單獨提供,即使它們是相同的。

常數

string 模組包含許多與 ASCII 和數字字符集相關的常量。

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
` % (name, value))
    
# output
# ascii_letters=`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`
# 
# ascii_lowercase=`abcdefghijklmnopqrstuvwxyz`
# 
# ascii_uppercase=`ABCDEFGHIJKLMNOPQRSTUVWXYZ`
# 
# digits=`0123456789`
# 
# hexdigits=`0123456789abcdefABCDEF`
# 
# octdigits=`01234567`
# 
# printable=`0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
# RSTUVWXYZ!"#$%&`()*+,-./:;<=>?@[\]^_`{|}~ 	

x0bx0c`
# 
# punctuation=`!"#$%&`()*+,-./:;<=>?@[\]^_`{|}~`
# 
# whitespace=` 	

x0bx0c`
複製程式碼

這些常量在處理 ASCII 資料時很有用,但由於在某種形式的 Unicode 中遇到非 ASCII 文字越來越常見,因此它們的應用受到限制。

相關文件:

pymotw.com/3/string/in…

相關文章