什么是正則表達式
- 用正則符號來描述字符串規(guī)則讓字符串匹配更簡單的一種工具; 正則本身的語法和語言無關(guān),幾乎所有的編程語言都支持正則
1、正則符號
1)普通字符:
?在正則表達式中沒有特殊功能或者特殊意義的字符都是普通字符
?普通字符在正則表達式中就代表這個符號本身,匹配的時候只能和這個指定的字符進行匹配
2)特殊字符:
. 匹配任意字符(一個點匹配一個字符)
\w ASCII碼表中只能匹配字母、數(shù)字、下劃線;ASCII碼表以外的都可以配(一個\w只能匹配一個字符)
\d 匹配一個數(shù)字字符(只能匹配一個數(shù)字)
\s 匹配任意一個空白字符
# \W,\D,\S 與小寫匹配的字符恰好相反
\W 匹配非數(shù)字字母下劃線
\D 匹配任意非數(shù)字
\S 匹配任意非空字符
代碼演示
# .(點)字符:匹配任意字符(一個點匹配一個字符)
re_str = r'a.b' # 匹配一個長度是3的字符串,第一個字符是a,最后一個字符是b, 中間是任意字符
print(re.fullmatch(re_str, 'abc')) # None
print(re.fullmatch(re_str, 'a你b'))
print(re.fullmatch(r'a..b', 'au9b'))
# \w字符:ASCII碼表中只能匹配字母、數(shù)字、下劃線;ASCII碼表以外的都可以配(一個\w只能匹配一個字符)
re_str = r'a\wb'
print(re.fullmatch(re_str, 'awb'))
print(re.fullmatch(re_str, 'a8b'))
print(re.fullmatch(re_str, 'a_b'))
print(re.fullmatch(re_str, 'a+b')) # None
print(re.fullmatch(re_str, 'a胡b'))
# \d - 匹配任意一個數(shù)字字符
re_str = r'a\d\db'
print(re.fullmatch(re_str, 'a23b'))
print(re.fullmatch(re_str, 'a33b'))
print(re.fullmatch(re_str, 'aa3b')) # None
# \s - 匹配任意一個空白字符
re_str = r'a\sb'
print(re.fullmatch(re_str, 'a b'))
print(re.fullmatch(re_str, 'a\tb'))
print(re.fullmatch(re_str, 'a\nb'))
print(re.fullmatch(re_str, 'a b')) # None
# \W, \D, \S
# \W 匹配非數(shù)字字母下劃線
# \D 匹配任意非數(shù)字
# \S 匹配任意非空字符
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c+d'))
print(re.fullmatch(r'a\Db\Sc\Wd', 'a2b=c+d')) # None
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb c+d')) # None
print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c胡d')) # None
[字符集] - 匹配字符集中的任意一個字符
注意: 一個[]只能匹配一個字符
a. [普通字符集] 例如: [abc] - 匹配a、b、c三個字符中的任意一個
[aA123] - 匹配a、A、1、2、3中的任意一個字符
b. [字符1-字符2] 例如: [1-9] - 匹配123456789中的任意一個字符
[0-9] - \d
[a-z] - 匹配任意一個小寫字母
[A-Z] - 匹配任意一個大寫字母
[a-zA-Z] - 匹配任意一個字母
[\u4e00-\u9fa5] - 匹配任意一個中文字符
[1-9abc] - 匹配1~9或者abc中的任意一個字符
[a-zA-Z0-9_] - 匹配字母數(shù)字下劃線
[\dxyz] - 任意數(shù)字或者x、y、z
注意: 字符1的編碼值必須小于字符2的編碼值
print(re.fullmatch(r'a[xyz89?]b', 'azb'))
print(re.fullmatch(r'a[xyz]b', 'anb'))
print(re.fullmatch(r'a[23456789]b', r'a7b'))
print(re.fullmatch(r'a[1-9abc]b', 'aab'))
print(re.fullmatch(r'a[abc1-9]b', 'aab'))
print(re.fullmatch(r'a[ac1-9b]b', 'aab'))
print(re.fullmatch(r'a[+*-]b', 'a-b'))
print(re.fullmatch(r'a[\dxyz]b', 'axb'))
print(re.fullmatch(r'a[\\dxyz]b', 'a\\b'))
[^字符集] - 匹配除了字符集以外的任意一個字符
[^abc] - 匹配除了abc以外的任意一個字符
[^1-9] - 匹配除了1~9以外的任意一個字符
print(re.fullmatch(r'a[^xyz]b', 'a=b')) # None
print(re.fullmatch(r'a[xyz^]b', 'a^b'))
2、檢測符號
- \b - 檢測是否是單詞結(jié)尾
單詞結(jié)尾 - 所有可以區(qū)分出兩個不同單詞的符號都是單詞結(jié)尾,其中字符串開頭和字符串結(jié)尾
用法: 檢測\b所在的位置是否是單詞結(jié)尾;不影響匹配的時候的字符串長度
# 匹配一個長度是3的字符串,第一個字符是a,最后一個字符是b,中間是任意一個數(shù)字;并且要求b的后面是單詞邊界
re_str = r'a\db\b'
print(re.fullmatch(re_str, 'a7b'))
re_str = r'a\bxy'
print(re.fullmatch(re_str, 'a xy')) # None
re_str = r'abc\b\sxyz'
print(re.fullmatch(re_str, 'abc xyz'))
result = re.search(r'\d\d\d\b', 'ashdjfhow2378how 899kah989sf 789')
print(result)
- ^ - 檢測字符串開頭
# 判斷^所在的位置是否是字符串開頭
re_str = r'^\d\d\d'
print(re.fullmatch(re_str, '123'))
print(re.search(re_str, 'k898ahs237khhj'))
# 3)$ - 檢測字符串結(jié)尾
re_str = r'\d\d\d$'
print(re.search(re_str, '123k898ahs237khhj990'))
re_str = r'^\d\d\d\d\d$'
3、匹配次數(shù)
?1) ? + *
? 匹配0次或1次
+ 匹配1次或多次
* 匹配0次或多次
# 1) ? - 匹配0次或1次
"""
x? - x出現(xiàn)0次或1次
\d? - 任意數(shù)字出現(xiàn)0次或1次
[a-z]? - 小寫字母出現(xiàn)0次或1次
"""
re_str = r'ax?b'
print(re.fullmatch(re_str, 'ab'))
print(re.fullmatch(re_str, 'axb'))
print(re.fullmatch(re_str, 'axxb')) # None
# 2) * - 匹配0次或多次
re_str = r'a\d*b' # r'a\d\d...\d\db'
print(re.fullmatch(re_str, 'ab'))
print(re.fullmatch(re_str, 'a2b'))
print(re.fullmatch(re_str, 'a12b'))
print(re.fullmatch(re_str, 'a1272937928329b'))
# 3) + - 匹配1次或多次
re_str = r'a\d+b'
print(re.fullmatch(re_str, 'ac')) # None
print(re.fullmatch(re_str, 'a2b'))
print(re.fullmatch(re_str, 'a12b'))
print(re.fullmatch(re_str, 'a1272937928329b'))
?2) {}
{N} - 匹配N次
{M,N} - 匹配M到N次: ? -> {0,1}
{M,} - 匹配至少M次 * -> {0,} + -> {1,}
{,N} - 匹配最多N次
re_str = r'a\d{5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))
re_str = r'a\d{3,5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))
re_str = r'a\d{5,}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))
re_str = r'a\d{,5}b'
print(re.fullmatch(re_str, 'a8867b'))
print(re.fullmatch(re_str, 'a88679b'))
print(re.fullmatch(re_str, 'a8867549b'))
?3) 貪婪和非貪婪
匹配次數(shù)不確定的時候有貪婪和非貪婪兩種狀態(tài)
?、*、+、{M,N}, {M,}, {,N} - 默認是貪婪的
??, *?, +?, {M,N}?, {M,}?, {,N}? - 非貪婪
貪婪 - 在能匹配成功的前提下,盡可能多的匹配
非貪婪 - 在能匹配成功的前提下,盡可能少的匹配
re_str = r'\d{3,5}'
re_str1 = r'\d{3,5}?'
print(re.search(re_str, 'abd54378'))
print(re.search(re_str1, 'abd54378'))
re_str = r'\d+'
re_str1 = r'\d+?'
print(re.search(re_str, 'fdj74389028729'))
print(re.search(re_str1, 'fdj74389028729'))
re_str = r'a.+b'
re_str1 = r'a.+?b'
print(re.search(re_str, '==aljfjkl745jbds322nfdjbv'))
print(re.search(re_str1, '==aljfjkl745jbds322nbfdjbv'))
3、分之與分組
1) | - 分之
- 正則1|正則2 --> 先讓正則1去匹配,如果匹配不成功再用正則2匹配;只要兩個中有一個能夠匹配成功就成功
# 匹配三個數(shù)字或者三個字母的字符串
re_str = r'\d{3}|[a-zA-Z]{3}'
print(re.fullmatch(re_str, '890'))
# 匹配一個字符串: abc前是3個數(shù)字或者3個字母
# 123abc, uJhabc
re_str = r'\d{3}abc|[a-zA-Z]{3}abc'
2) () - 分組
(正則表達式) - 將正則表達式看成一個整體進行操作
整體控制次數(shù): ()匹配次數(shù)
重復: 帶分組的正則表達式\M -- 在\M的位置重前面第M個分組匹配到的內(nèi)容
# ab78hj90lo23
re_str = r'[a-z]{2}\d{2}[a-z]{2}\d{2}[a-z]{2}\d{2}'
# 9h8k9j8j7h6u5k....
re_str = r'(\d[a-z])+'
# 匹配一個字符串: abc前是3個數(shù)字或者3個字母
re_str = r'(\d{3}|[a-z]{3})abc'
print(re.fullmatch(re_str, 'mskabc'))
# abc123abc -成功! xab234xab - 成功! xyz123xyz -成功!
# abc123acb -失敗! xab234sdk -失??!
# ab-ab abc-abc 123-123
re_str = r'(\d+)abc\1'
print(re.fullmatch(re_str, '234abc234'))
print(re.fullmatch(re_str, '12345abc12345'))
print(re.fullmatch(re_str, '234abc890')) # None
re_str = r'(\d+)([a-z]+)=\2'
print(re.fullmatch(re_str, '6kh=kh'))
re_str = r'(\d+)=\1([a-z]+)'
print(re.fullmatch(re_str, '123=123ioo'))
re_str = r'(\d{3})=(\1){2}'
print(re.fullmatch(re_str, '234=234234'))