【背景】
Python中的正則表達式方面的功能,很強大。
其中就包括re.sub,實現正則的替換。
功能很強大,所以導致用法稍微有點複雜。
所以當遇到稍微複雜的用法時候,就容易犯錯。
所以此處,總結一下,在使用re.sub的時候,需要注意的一些事情。
解釋具體的注意事項之前,先把其具體的解釋貼出來:
|
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 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
舉例說明:
繼續之前的例子,假如對於匹配到的內容,只處理其中一部分。
比如對於:
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 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中了
否則就會出現我這裏:
遇到的問題:
當傳遞第三個參數,原以爲是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 |
纔可以正常工作。