Python 使用界定符分割字符串

使用界定符分割字符串


前言


需求是將字符串分割成多段,但是分隔符(周圍的空格)并不固定。

re.split()


普通 string 對象的 split() 方法能夠用于字符串分割,但前提是需求相對簡單的情況下,因?yàn)?string 對象的 split() 方法并不允許有多個(gè)分隔符或者分隔符周圍有不確定的空格。當(dāng)需要更加靈活地切割字符的時(shí)候,建議使用 re.split() 方法。示例如下:

>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

re.split() 允許為分隔符指定多個(gè)正則模式,上面的示例中表示,分隔符可以是分號、逗號或者空格,并且后面緊跟任意空格。只要這個(gè)模式被找到,那么匹配的分隔符兩邊的實(shí)體都會(huì)別當(dāng)成是結(jié)果中的元素返回。返回結(jié)果類型是列表。

maxsplit 和 flags 參數(shù)


這里延伸講下 re.split() 函數(shù)的參數(shù),該函數(shù)的完整表達(dá)形式如下:

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

  • pattern 就是分割模式;
  • string 就是代表待分割的字符串;
  • maxsplit默認(rèn)為 0,但如果這個(gè)參數(shù)非零,函數(shù)最多進(jìn)行 maxsplit 次分割,剩下的字符全部返回到列表的最后一個(gè)元素中;
  • flags 參數(shù)為可選標(biāo)記參數(shù),例如 re.M,re.I 等。

實(shí)例代碼演示 maxsplit 參數(shù)的效果

>>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'\W+', 'Words, words, words.', 1)
['Words', 'words, words.']

在第二段代碼中,函數(shù)只分割了一次,剩余元素都在列表中的最后一個(gè)元素中。

下面這段代碼是 flags 這個(gè)參數(shù)的一個(gè)應(yīng)用:

>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
>>> re.split('[a-f]+', '0a3B9', flags=re.I)
['0', '3', '9']

這里指定的標(biāo)記參數(shù)是 re.Ire.IGNORECASE,但是兩者的效果等同,這兩者的作用是用于在匹配時(shí)忽略大小寫。

捕獲分組


使用 re.split() 函數(shù)的時(shí)候,還需要注意正則表達(dá)式是否包含一個(gè)括號的捕獲分組,如果在 pattern 中捕獲到括號,那么所有被匹配的文本,都會(huì)被當(dāng)成一部分返回在列表里。示例如下:

>>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

\W 用于匹配特殊字符,在例子第二段代碼中,被匹配的字符,也作為一部分內(nèi)容返回在列表中。第三段代碼,表示的是,分割模式有捕獲分組,并且匹配到字符串的開始,那么結(jié)果將以一個(gè)空字符串開始,對于結(jié)尾也一樣。

如果不想保留分割字符到結(jié)果列表中,但仍然需要使用到括號來分組的情況下,可以用 (?:...) 來表達(dá)分組是非捕獲組,例如:

>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'(?:\W+)', 'Words, words, words.')
['Words', 'words', 'words', '']

注意事項(xiàng)


本篇文章運(yùn)行環(huán)境中,Python 的版本是 3.6 ,在未升級到 3.7 的版本中, split() 函數(shù)并不支持空匹配模式,例如,文檔中給出的注解:

Note: split() doesn’t currently split a string on an empty pattern match.

先給出示例代碼:

>>> re.split('x*', 'axbc')
...: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)
['a', 'bc']

正常情況下,x* 是能夠匹配 0 個(gè) x,無論是在 a 之前,bc 之間還是 c 之后,然而這些都被忽略了。正確的結(jié)果應(yīng)該是形如 ['', 'a', 'b', 'c', ''],但這是一個(gè)向后不兼容的更改,所以會(huì)有 FutureWarning 警告拋出。

在 Python 3.6 中,空匹配模式還不被允許,強(qiáng)行使用的話,會(huì)拋出 ValueError 異常。例如:

>>> re.split("^$", 'foo\n\nbar\n', flags=re.M)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ...
ValueError: split() requires a non-empty pattern match.

但這部分內(nèi)容,已經(jīng)在 3.7 中做出了改動(dòng)。在 3.8 版本中的文檔中,有部分小注:

Changed in version 3.7: Added support of splitting on a pattern that could match an empty string.

這部分內(nèi)容表明,在 3.7版后 re.split() 已經(jīng)開始支持空匹配模式。

所以,如果使用 re.split() 空匹配模式的時(shí)候,效果未達(dá)預(yù)期,可以考慮是否是 Python 版本的原因。

以上就是本篇的主要內(nèi)容

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

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