2018年10月29日 星期一

Python小技巧-字串

使用多個分隔符號分解字串
分解字串最簡單的方式就是 split() 方法,例如:
str1 = 'food book my foo'
print(str1.split(' '))  #['food', 'book', 'my', 'foo']
split() 方法只能有一個分隔字元。如果要以多個分隔字元分解字串,需執行多次 split() 方法。
re.split() 方法可以同時使用多個分隔字元分解字串,例如:
import re
str1 = 'food book; my,       foo'
print(re.split(r'[;,\s]\s*', str1))  #['food', 'book', 'my', 'foo']
上例同時以「;」、「,」、空格、多個空格分解字串。



同時比對多個字串的開頭或結尾文字
檢查字串開頭文字的方法為startswith() 方法,檢查字串結尾文字的方法為endswith() 方法,例如:
url = 'http://www.e-happy.com.tw/index.html'
print(url.startswith('http'))  #TRUE
print(url.endswith('html'))  #TRUE
如果要同時比對多個文字,可將比對文字組成元組做為參數。例如要比對檔案是否為圖形檔案,可比對檔案名稱結尾是否為「.jpg」、「.png」、「.bmp」:
Filename = 'd:/t1/face.jpg'
print(filename.endswith((‘.jpg’, ‘.png’, ’.bmp’))  #TRUE


以萬用字元比對字串中文字
萬用字元以「*」代表多個字元,「?」代表一個字元。
Fnmatch 模組提供以萬用字元比對字串功能:fnmatch() 方法以不區分大小寫方式比對,fnmatchcase() 方法以區分大小寫方式比對。例如:
from fnmatch import fnmatch, fnmatchcase
print(fnmatch('good.txt', '*.txt'))  # True
print(fnmatch('good.txt', '?.txt'))  # False
print(fnmatch('good.txt', '?ood.txt'))  # True
print(fnmatch('good.txt', '*.TXT'))  # True
print(fnmatchcase('good.txt', '*.TXT'))  # False

較複雜的取代文字
字串中簡單的文字取代可使用 string.replace() 方法。例如:
str1 = 'yes, no, yes, or'
print(str1.replace('yes', 'ok'))  # ok, no, ok, or
若要做較複雜的取代文字,可使用 re 模組的 sub() 方法。例如要將日期格式由「mm/dd/yyyy」轉換為「yyyy-mm-dd」。
import re
str1 = '今天是 10/9/2018, 昨天是 10/8/2018'
print(re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', str1))  #今天是 2018-10-9, 昨天是 2018-10-8
sub() 方法的第一個參數是正規表達式的搜尋字串,第二個參數是替換的模式:反斜線加上數字是正規表達式的捕捉組,「\1」為第 1 個捕捉組,「\2」為第 2 個捕捉組,依此類推。例如上面例子以「(\d+)/(\d+)/(\d+)」搜尋「10/9/2018」,「\1」即為「10」,「\2」即為「9」,「\3」即為「2018」。
另外,re.sub() 還提供 「flags = re.IGNORECASE」做為不區分大小寫的文字取代:
import re
str1 = 'Book, book, BOOK'
print(re.sub('book', 'python', str1, flags = re.IGNORECASE))  #python, python, python


移除頭尾特定字元
strip() 方法會移除字串前後的空白,lstrip() 方法會移除字串前方的空白,rstrip() 方法會移除字串後方的空白。三個方法都不會移除字串中間的空白。例如:
str1 = '   我是 學生 '
print(str1.strip())  # '我是 學生'
print(str1.lstrip())  # '我是 學生 '
print(str1.rstrip())  # ' 我是 學生'
上面三個方法可以將要移除的字元做為參數傳入,就可移除指定字元 (即移除字元預設為空白字元)。若傳入多個字元,則每個字元都會移除。例如:
str1 = '------我是學生========'
print(str1.strip('-'))  #我是學生========
print(str1.strip('='))  #------我是學生
print(str1.strip('-='))  #我是學生


輸出格式化
輸出資料時,常有要對齊資料的需求,format() 方法可以輕易達成要求。format() 以「>」表示靠右對齊,「<」表示靠左對齊,「^」表示置中對齊。例如:
str1 = 'python'
print(format(str1, '>15'))  #' python'
print(format(str1, '<15'))  #'python '
print(format(str1, '^15'))  #' python '
也可在對齊字元加入空格以外的填補字元,例如:
str1 = 'python'
print(format(str1, '=>15'))  #'=========python'
print(format(str1, '+>15'))  #'+++++++++python'
format() 方法也可以同時顯示多個值,例如:
print('{:>10}  {:>8}'.format('python', 'good'))  #' python good'
format() 方法不僅用於字串,也可用於數值顯示,例如:
n = 9.876
print(format(n, '>10'))  #' 9.876'
print(format(n, '>10.1f'))  #' 9.9'


連接串列中的字串
串列中的字串可用 join() 方法連接為一個字串,例如:
slist = ['I', 'like', 'python', 'very', 'much']
print(' '.join(slist))  #I like python very much
join() 方法前面的字串是分隔字串,各原始字串會以此字串分隔,例如:
slist = ['I', 'like', 'python', 'very', 'much']
print('=='.join(slist))  #I==like==python==very==much
注意:連接串列中的字串也可使用迴圈達成,例如:
slist = ['I', 'like', 'python', 'very', 'much']
s = ''
for s1 in slist:
   s = s + s1 + ' '
print(s)  #I like python very much
但使用迴圈方式的效率遠較 join() 方法低,故盡量使用 join() 方法。


在字串中插入變數值
若能在字串中顯示變數值是一項相當方便的功能,只要結合 format_map() 及 vars() 就能輕鬆達成目的。例如:
s = '{name} 的國文成績: {score} 分'
name = 'David'
score = 90
print(s.format_map(vars()))  # David 的國文成績: 90 分
如此就能在字串中顯示 name 及 score 變數值。
這方法有一個缺點:若使用的變數不存在,將產生錯誤而使程式中斷。解決方法是以 __missing__() 方法定義一個替代字典類別。例如:
class missvar(dict):
   def __missing__(self, key):
       return '{%s}' % key
s = '{name} 的國文成績: {score} 分'
name = 'David'
print(s.format_map(missvar(vars())))  # David 的國文成績: {score} 分
若變數不存在,會直接顯示變數名稱。

沒有留言:

張貼留言