python3: 字串和文字(3)

阿里瓜瓜發表於2019-01-30

11. 刪除字串中不需要的字元

 strip() 方法能用於刪除開始或結尾的字元;

 lstrip() 和 rstrip() 分別從左和從右執行刪除操作

>>> s = ' hello     world \n'
>>> s = s.strip()
>>> s
'hello     world'
>>>

如果你想處理中間的空格,那麼你需要求助其他技術。比如使用 replace() 方法或者是用正規表示式re.sub()替換。示例如下:

>>> s.replace(' ', '')
'helloworld'
>>> import re
>>> re.sub('\s+', ' ', s)
'hello world'
>>>

\s+: 匹配空格1次~多次

對於更高階的strip,你可能需要使用 translate() 方法

12. 審查清理文字字串

s = 'pýtĥöñ\fis\tawesome\r\n'
>>> remap = {
...     ord('\t') : ' ',
...     ord('\f') : ' ',
...     ord('\r') : None # Deleted
... }
>>> a = s.translate(remap)
>>> a
'pýtĥöñ is awesome\n'

你可以以這個表格為基礎進一步構建更大的表格。比如,讓我們刪除所有的和音符

>>> import unicodedata
>>> import sys
>>> cmb_chrs = dict.fromkeys(c for c in range(sys.maxunicode)
...                         if unicodedata.combining(chr(c)))
...
>>> b = unicodedata.normalize('NFD', a)
>>> b
'pýtĥöñ is awesome\n'
>>> b.translate(cmb_chrs)
'python is awesome\n'
>>>

通過使用 dict.fromkeys() 方法構造一個字典,每個Unicode和音符作為鍵,對應的值全部為 None 。

13. 字串對齊[format]

對於基本的字串對齊操作,可以使用字串的 ljust() , rjust() 和 center() 方法

>>> text = 'Hello World'
>>> text.ljust(20)
'Hello World         '
>>> text.rjust(20)
'         Hello World'
>>> text.center(20)
'    Hello World     '
>>>

所有這些方法都能接受一個可選的填充字元。比如:

>>> text.rjust(20,'=')
'=========Hello World'
>>> text.center(20,'*')
'****Hello World*****'
>>>

函式 format() 同樣可以用來很容易的對齊字串。 你要做的就是使用 <,> 或者 ^ 字元後面緊跟一個指定的寬度。比如:

>>> format(text, '>20')
'         Hello World'
>>> format(text, '<20')
'Hello World         '
>>> format(text, '^20')
'    Hello World     '
>>>

如果你想指定一個非空格的填充字元,將它寫到對齊字元的前面即可: 

>>> format(text, '=>20s')
'=========Hello World'
>>> format(text, '*^20s')
'****Hello World*****'
>>>

當格式化多個值的時候,這些格式程式碼也可以被用在 format() 方法中。比如:

>>> x = 1.2345
>>> format(x, '>10')
'    1.2345'
>>> format(x, '^10.2f')
'   1.23   '
>>>

14. 合併拼接字串(join, +)

如果你想要合併的字串是在一個序列或者 iterable 中,那麼最快的方式就是使用 join() 方法。比如:

>>> parts = ['Is', 'Chicago', 'Not', 'Chicago?']
>>> ' '.join(parts)
'Is Chicago Not Chicago?'
>>> ','.join(parts)
'Is,Chicago,Not,Chicago?'
>>> ''.join(parts)
'IsChicagoNotChicago?'
>>>

合併少數幾個字串,使用加號(+)通常已經足夠了:

>>> a = 'Is Chicago'
>>> b = 'Not Chicago?'
>>> a + ' ' + b
'Is Chicago Not Chicago?'
>>>

加號(+)操作符在作為一些複雜字串格式化的替代方案的時候通常也工作的很好,比如: 

>>> print('{} {}'.format(a,b))
Is Chicago Not Chicago?
>>> print(a + ' ' + b)
Is Chicago Not Chicago?
>>>

如果你想在原始碼中將兩個字面字串合併起來,你只需要簡單的將它們放到一起,不需要用加號(+)。比如:

>>> a = 'Hello' 'World'
>>> a
'HelloWorld'
>>>

最重要的需要引起注意的是,當我們使用加號(+)操作符去連線大量的字串的時候是非常低效率的, 因為加號連線會引起記憶體複製以及垃圾回收操作。 特別的,你永遠都不應像下面這樣寫字串連線程式碼: 

s = ''
for p in parts:
    s += p

一個相對比較聰明的技巧是利用生成器表示式(參考1.19小節)轉換資料為字串的同時合併字串,比如: 

>>> data = ['ACME', 50, 91.1]
>>> ','.join(str(d) for d in data)
'ACME,50,91.1'
>>>

同樣還得注意不必要的字串連線操作。有時候程式設計師在沒有必要做連線操作的時候仍然多此一舉。比如在列印的時候:

print(a + ':' + b + ':' + c) # Ugly
print(':'.join([a, b, c])) # Still ugly
print(a, b, c, sep=':') # Better

15. 字串中插入變數

>>> s = '{name} has {n} messages.'
>>> s.format(name='Guido', n=37)
'Guido has 37 messages.'
>>>

如果要被替換的變數能在變數域中找到, 那麼你可以結合使用 format_map() 和 vars() 。就像下面這樣

>>> name = 'Guido'
>>> n = 37
>>> s.format_map(vars())
'Guido has 37 messages.'
>>>

vars() 還有一個有意思的特性就是它也適用於物件例項。比如:

>>> class Info:
...     def __init__(self, name, n):
...         self.name = name
...         self.n = n
...
>>> a = Info('Guido',37)
>>> s.format_map(vars(a))
'Guido has 37 messages.'
>>>

format 和 format_map() 的一個缺陷就是它們並不能很好的處理變數缺失的情況,比如:

>>> s.format(name='Guido')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'n'
>>>

 一種避免這種錯誤的方法是另外定義一個含有 __missing__() 方法的字典物件,就像下面這樣:

class safesub(dict):
"""防止key找不到"""
    def __missing__(self, key):
        return '{' + key + '}'

現在你可以利用這個類包裝輸入後傳遞給 format_map()

>>> del n # Make sure n is undefined
>>> s.format_map(safesub(vars()))
'Guido has {n} messages.'
>>>

如果你發現自己在程式碼中頻繁的執行這些步驟,你可以將變數替換步驟用一個工具函式封裝起來。就像下面這樣:

import sys

def sub(text):
    return text.format_map(safesub(sys._getframe(1).f_locals))

現在你可以像下面這樣寫了:

>>> name = 'Guido'
>>> n = 37
>>> print(sub('Hello {name}'))
Hello Guido
>>> print(sub('You have {n} messages.'))
You have 37 messages.
>>> print(sub('Your favorite color is {color}'))
Your favorite color is {color}
>>>

 

可以使用字串模版

>>> import string
>>> s = string.Template('$name has $n messages.')
>>> s.substitute(vars())
'Guido has 37 messages.'
>>>

 

相關文章