【python字符串】基礎(chǔ)知識補課

2018.04.15 已經(jīng)用python一段時間了,最近遇到幾個與字符串相關(guān)的問題,雖然最后都解決了,但很不pythonic,所以決定回補字符串相關(guān)基礎(chǔ)知識。

參考資料:

python3中文版參考-第二章:字符串和文本
小甲魚 字符串:格式化 – 零基礎(chǔ)入門學(xué)習Python015

先看基礎(chǔ)——正則表達

參考:python正則表達式系列(1)——正則元字符
why?因為字符串的處理除了用到python的str方法之外,很多時候還需要用到re正則模塊中更加強大、靈活的方法進行處理,而后者的重要基礎(chǔ)就是正則。因此,想要靈活處理字符串問題,就必須先掌握正則基礎(chǔ)。
正則元字符:. ^ $ * + ? { } [ ] \ | ( )

A 元字符之[ ]——指定字符集
正則表達式[]里的五個特殊字符
通常的字符集匹配:

  • [abc]匹配:a或b或c
  • [^a]匹配:匹配非a的一個字符;
  • [a-zA-Z0-9]匹配:大小寫英文字母和數(shù)字
  • [^0-9]匹配:不包含0123456789的其他任意字符

然而,
① [ ] - \ ^五個字符在[ ]中都有著特殊意義,而其余的元字符.、*、+、|在[ ]中均不再保留任何特殊意義;
②因此,若要在[]中匹配[ ]-\^五個元字符一定要添加反義字符 \

  • [\^a\-bc]匹配:^和a和-和b和c共五個字符組成的字符集
  • [a+]匹配:a或+
  • [*\-+]匹配:* - + 推薦!
  • [*-+]這個表達式其實表示的是*的ASCII值到+的ASCII值的范圍。不推薦!
  • [+-*]將會報錯,就像你不能寫成[9-0]一樣,因為+、*的ASCII值大小順序反了。錯誤!

B 元字符之()——匹配 pattern 并保留匹配符號
正則表達式 - 元字符
(pattern): 匹配 pattern 并獲取這一匹配;
(?:pattern): 匹配 pattern 但不獲取匹配結(jié)果;
(?=pattern):正向肯定預(yù)查(look ahead positive assert),在任何匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。
(?!pattern):正向否定預(yù)查(negative assert),在任何不匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。
(?<=pattern):反向(look behind)肯定預(yù)查,與正向肯定預(yù)查類似,只是方向相反。
(?<!pattern):反向否定預(yù)查,與正向否定預(yù)查類似,只是方向相反。

C 元字符之{ }——匹配前一個字符或子表達式出現(xiàn)指定次數(shù)
例如:

  • {0,}:0次或多次,相當于*
  • {1,}:1次或多次,相當于+
  • {0,1}:0次或1次,相當于?
  • {m,n}:m次到n次(m <= n)

1 字符串分割:str.split()和re.split()

參考:
Python字符串分割方法總結(jié)
中文說明 2.1 使用多個界定符分割字符串

1.1 str.split()方法

S.split(sep=None, maxsplit=-1) 

返回的是一個list

  • sep為分隔符,默認以空白字符whitespace (空格,TAB和回車)為分隔符;
  • maxsplit為最大分割次數(shù),當指定最大分割次數(shù)maxsplit時,結(jié)果列表長度為maxsplit+1。;
  • print(str.split._ doc _)查看相關(guān)說明
  • 缺點:sep只能指定一個分隔符??!

1.2 re.split()方法

re.split(pattern, string, maxsplit=0, flags=0)

返回的是一個list

  • pattern相當于sep的功能,但它是更加靈活的正則表達式;
  • string為目標字符串;
  • maxsplit為最大分割次數(shù),當指定最大分割次數(shù)maxsplit時,結(jié)果列表長度為maxsplit+1;
  • flags為標志,表示正則表達式用到的標志。
    核心:可以用靈活的正則表達式作為分隔符
    ①用[ ]符號:表示字符集,無需再用或,也不加逗號。
import re
line = 'asdf fjdk; afed, fjek,asdf, foo'
re.split(r'[,;\s]\s*', line)

Out[5]: ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

②用()符號:保留分割符號

line = 'asdf fjdk; afed, fjek,asdf, foo'
fields = re.split(r'(;|,|\s)\s*', line)

Out[6]: ['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']

2. 字符串開頭、結(jié)尾匹配:str.startwith()、str.endwith()

經(jīng)常用于文件名、擴展名的快速優(yōu)雅匹配

>>> filename = 'spam.txt'
>>> filename.endswith('.txt')
True
>>> filename.startswith('file:')
False

返回的是True、False,經(jīng)常用作if 的判斷參數(shù),將if嵌入for循環(huán)中進行列表快速篩選!
經(jīng)典用法1:快速篩選有效數(shù)據(jù)生成list

>>> filenames
[ 'Makefile', 'foo.c', 'bar.py', 'spam.c', 'spam.h' ]
>>> [name for name in filenames if name.endswith(('.c', '.h')) ]
['foo.c', 'spam.c', 'spam.h'

經(jīng)典用法2:檢查某個文件夾中是否存在指定的文件類型

if any(name.endswith(('.c', '.h')) for name in listdir(dirname)):
  

str.startwith()、str.endwith()的功能用切片比對的方法也能實現(xiàn),但那樣很不優(yōu)雅!

3.用通配符匹配字符串:fnmatch() 和 fnmatchcase()

與前述的str.startwith()、str.endwith()是字符串精準匹配,而fnmatch() 和 fnmatchcase()可以用通配符進行更加靈活的匹配

from fnmatch import fnmatch, fnmatchcase
#導(dǎo)入fnmatch模塊的相關(guān)方法
fnmatch('foo.txt', '*.txt')

經(jīng)典用法:

import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '505996-*-2017.txt'):
        print(file)

4.字符串匹配和搜索:str.find() , str.endswith() , str.startswith()和re.match()

str.find():返回的是字符串在str中第一次出現(xiàn)的位置(int)

text = 'yeah, but no, but yeah, but no, but yeah'
text.find('no')  #返回的是字符串在str中第一次出現(xiàn)的位置(int)
10

re.match():

text1 = '11/27/2012'
if re.match(r'\d+/\d+/\d+', text1):
print('yes')

5.字符串中插入變量:{}和format()方法

參考:2.15 字符串中插入變量

>>> s = '{name} has {n} messages.'
#用{ }來定義變量
>>> s.format(name='Guido', n=37)
#用str.format(變量=vlaue)來給字符串中的變量賦值
out: 'Guido has 37 messages.'

應(yīng)用場景:爬蟲中多頁的url地址,切換{num}url中的頁碼變量

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容