詳解Python中re.sub

【背景】
Python中的正則表達式方面的功能锅尘,很強大监氢。
其中就包括re.sub,實現正則的替換藤违。
功能很強大,所以導致用法稍微有點復雜纵揍。
所以當遇到稍微復雜的用法時候顿乒,就容易犯錯。
所以此處泽谨,總結一下璧榄,在使用re.sub的時候,需要注意的一些事情吧雹。

解釋具體的注意事項之前骨杂,先把其具體的解釋貼出來:
re.sub
re.
sub
(
pattern, repl, string, count=0, flags=0)

Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. If the pattern isn’t found, string is returned unchanged. repl can be a string or a function; if it is a string, any backslash escapes in it are processed. That is,\n
is converted to a single newline character,\r
is converted to a carriage return, and so forth. Unknown escapes such as\j
are left alone. Backreferences, such as\6
, are replaced with the substring matched by group 6 in the pattern. For example:

re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9])\s(\s):',... r'static PyObject\npy_\1(void)\n{',... 'def myfunc():')'static PyObject\npy_myfunc(void)\n{'
If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single match object argument, and returns the replacement string. For example:
def dashrepl(matchobj):... if matchobj.group(0) == '-': return ' '... else: return '-'>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')'pro--gram files'>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)'Baked Beans & Spam'
The pattern may be a string or an RE object.
The optional argument count is the maximum number of pattern occurrences to be replaced; count must be a non-negative integer. If omitted or zero, all occurrences will be replaced. Empty matches for the pattern are replaced only when not adjacent to a previous match, sosub('x
', '-', 'abc')
returns'-a-b-c-'
.
In addition to character escapes and backreferences as described above,\g<name>
will use the substring matched by the group namedname
, as defined by the(?P<name>...)
syntax.\g<number>
uses the corresponding group number;\g<2>
is therefore equivalent to\2
, but isn’t ambiguous in a replacement such as\g<2>0
.\20
would be interpreted as a reference to group 20, not a reference to group 2 followed by the literal character'0'
. The backreference\g<0>
substitutes in the entire substring matched by the RE.
Changed in version 2.7: Added the optional flags argument.

re.sub的功能
re是regular expression的所寫,表示正則表達式
sub是substitute的所寫雄卷,表示替換搓蚪;
re.sub是個正則表達式方面的函數,用來實現通過正則表達式丁鹉,實現比普通字符串的replace更加強大的替換功能妒潭;
舉個最簡單的例子:
如果輸入字符串是:
?
1

inputStr

"hello 111 world 111"

那么你可以通過
?
1

replacedStr

inputStr.replace(
"111"
,
"222"
)

去換成
"hello 222 world 222"

但是,如果輸入字符串是:
?
1

inputStr

"hello 123 world 456"

而你是想把123和456揣钦,都換成222
(以及其他還有更多的復雜的情況的時候)雳灾,
那么就沒法直接通過字符串的replace達到這一目的了。
就需要借助于re.sub冯凹,通過正則表達式谎亩,來實現這種相對復雜的字符串的替換:
?
1

replacedStr

re.sub(
"\d+"
,
"222"
, inputStr)

當然,實際情況中宇姚,會有比這個例子更加復雜的匈庭,其他各種特殊情況,就只能通過此re.sub去實現如此復雜的替換的功能了空凸。
所以嚎花,re.sub的含義,作用呀洲,功能就是:
對于輸入的一個字符串紊选,利用正則表達式(的強大的字符串處理功能)啼止,去實現(相對復雜的)字符串替換處理,然后返回被替換后的字符串
其中re.sub還支持各種參數兵罢,比如count指定要替換的個數等等献烦。
下面就是來詳細解釋其各個參數的含義。

re.sub的各個參數的詳細解釋
re.sub共有五個參數卖词。
其中三個必選參數:pattern, repl, string
兩個可選參數:count, flags

第一個參數:pattern
pattern巩那,表示正則中的模式字符串,這個沒太多要解釋的此蜈。
需要知道的是:
反斜杠加數字(\N)即横,則對應著匹配的組(matched group)比如\6,表示匹配前面pattern中的第6個group
意味著裆赵,pattern中东囚,前面肯定是存在對應的,第6個group战授,然后你后面也才能去引用

比如页藻,想要處理:
hello crifan, nihao crifan

且此處的,前后的crifan植兰,肯定是一樣的份帐。
而想要把整個這樣的字符串,換成crifanli
則就可以這樣的re.sub實現替換:
?
1
2
3

inputStr

"hello crifan, nihao crifan"
;

replacedStr

re.sub(r
"hello (\w+), nihao \1"
,
"crifanli"
, inputStr);

print
"replacedStr="
,replacedStr;

crifanli

第二個參數:repl
repl楣导,就是replacement废境,被替換,的字符串的意思爷辙。
repl可以是字符串彬坏,也可以是函數。

repl是字符串

如果repl是字符串的話膝晾,其中的任何反斜杠轉義字符栓始,都會被處理的。
即:
\n:會被處理為對應的換行符血当;
\r:會被處理為回車符幻赚;
其他不能識別的轉移字符,則只是被識別為普通的字符:比如\j臊旭,會被處理為j這個字母本身落恼;

反斜杠加g以及中括號內一個名字,即:\g<name>离熏,對應著命了名的組佳谦,named group

接著上面的舉例:
想要把對應的:
hello crifan, nihao crifan

中的crifan提取出來,只剩:
crifan

就可以寫成:
?
1
2
3

inputStr

"hello crifan, nihao crifan"
;

replacedStr

re.sub(r
"hello (\w+), nihao \1"
,
"\g<1>"
, inputStr);

print
"replacedStr="
,replacedStr;

crifan

對應的帶命名的組(named group)的版本是:
?
1
2
3

inputStr

"hello crifan, nihao crifan"
;

replacedStr

re.sub(r
"hello (?P<name>\w+), nihao (?P=name)"
,
"\g<name>"
, inputStr);

print
"replacedStr="
,replacedStr;

crifan

repl是函數

舉例說明:
比如輸入內容是:
hello 123 world 456

想要把其中的數字部分滋戳,都加上111钻蔑,變成:
hello 234 world 567

那么就可以寫成:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

!/usr/bin/python

-- coding: utf-8 --

"""

Function:

【整理】詳解Python中re.sub

http://www.crifan.com/python_re_sub_detailed_introduction

Version: 2013-05-02

Author: Crifan

Contact: admin (at) crifan.com

"""

import
re;

def
pythonReSubDemo():

"""

demo Pyton re.sub

"""

inputStr

"hello 123 world 456"
;

def
_add111(matched):

intStr

matched.group(
"number"
);

123

intValue

int
(intStr);

addedValue

intValue

111
;

234

addedValueStr

str
(addedValue);

return
addedValueStr;

replacedStr

re.sub(
"(?P<number>\d+)"
, _add111, inputStr);

print
"replacedStr="
,replacedStr;

hello 234 world 567

###############################################################################

if
name
=
=
"main"
:

pythonReSubDemo();

第三個參數:string
string啥刻,即表示要被處理,要被替換的那個string字符串咪笑。
沒什么特殊要說明可帽。

第四個參數:count
舉例說明:
繼續(xù)之前的例子,假如對于匹配到的內容窗怒,只處理其中一部分映跟。
比如對于:
hello 123 world 456 nihao 789

只是像要處理前面兩個數字:123,456,分別給他們加111扬虚,而不處理789努隙,
那么就可以寫成:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

!/usr/bin/python

-- coding: utf-8 --

"""

Function:

【整理】詳解Python中re.sub

http://www.crifan.com/python_re_sub_detailed_introduction

Version: 2013-05-02

Author: Crifan

Contact: admin (at) crifan.com

"""

import
re;

def
pythonReSubDemo():

"""

demo Pyton re.sub

"""

inputStr

"hello 123 world 456 nihao 789"
;

def
_add111(matched):

intStr

matched.group(
"number"
);

123

intValue

int
(intStr);

addedValue

intValue

111
;

234

addedValueStr

str
(addedValue);

return
addedValueStr;

replacedStr

re.sub(
"(?P<number>\d+)"
, _add111, inputStr,
2
);

print
"replacedStr="
,replacedStr;

hello 234 world 567 nihao 789

###############################################################################

if
name
=
=
"main"
:

pythonReSubDemo();

第五個參數:flags

關于re.sub的注意事項
然后再來整理一些,關于re.sub的注意事項孔轴,常見的問題及解決辦法:

要注意剃法,被替換的字符串,即參數repl路鹰,是普通的字符串,不是pattern
注意到收厨,語法是:
?
1

re.sub(pattern, repl, string, count

0
, flags
=
0
)

即晋柱,對應的第二個參數是repl。
需要你指定對應的r前綴诵叁,才是pattern:
r"xxxx"

不要誤把第四個參數flag的值雁竞,傳遞到第三個參數count中了
否則就會出現我這里:
【已解決】Python中,(1)re.compile后再sub可以工作拧额,但re.sub不工作碑诉,或者是(2)re.search后replace工作,但直接re.sub以及re.compile后再re.sub都不工作
遇到的問題:
當傳遞第三個參數侥锦,原以為是flag的值是进栽,
結果實際上是count的值
所以導致re.sub不功能,
所以要參數指定清楚了:
?
1

replacedStr

re.sub(replacePattern, orignialStr, replacedPartStr, flags

re.I);

can omit count parameter

或:
?
1

replacedStr

re.sub(replacePattern, orignialStr, replacedPartStr,
1
, re.I);

must designate count parameter

才可以正常工作恭垦。https://www.crifan.com/python_re_sub_detailed_introduction/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末快毛,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子番挺,更是在濱河造成了極大的恐慌唠帝,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玄柏,死亡現場離奇詭異襟衰,居然都是意外死亡,警方通過查閱死者的電腦和手機粪摘,發(fā)現死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門瀑晒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绍坝,“玉大人,你說我怎么就攤上這事瑰妄∠葑欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵间坐,是天一觀的道長灾挨。 經常有香客問我,道長竹宋,這世上最難降的妖魔是什么劳澄? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮蜈七,結果婚禮上秒拔,老公的妹妹穿的比我還像新娘。我一直安慰自己飒硅,他們只是感情好砂缩,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著三娩,像睡著了一般庵芭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雀监,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天双吆,我揣著相機與錄音,去河邊找鬼会前。 笑死好乐,一個胖子當著我的面吹牛,可吹牛的內容都是我干的瓦宜。 我是一名探鬼主播蔚万,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歉提!你這毒婦竟也來了笛坦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤苔巨,失蹤者是張志新(化名)和其女友劉穎版扩,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體侄泽,經...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡礁芦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柿扣。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡肖方,死狀恐怖,靈堂內的尸體忽然破棺而出未状,到底是詐尸還是另有隱情俯画,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布司草,位于F島的核電站艰垂,受9級特大地震影響,放射性物質發(fā)生泄漏埋虹。R本人自食惡果不足惜猜憎,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搔课。 院中可真熱鬧胰柑,春花似錦、人聲如沸爬泥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袍啡。三九已至姐浮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間葬馋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工肾扰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畴嘶,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓集晚,卻偏偏與公主長得像窗悯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子偷拔,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內容