常見的原子類型有哪些?
1.普通字符作原子
2.非打印字符作原子
3.通用字符作爲原子
4.原子表
** 1.普通字符作原子:**
普通字符是編寫正則表達式時最常見的原子了,包括所有的大寫和小寫字母字符、所有數字等。例如,a—z、A—Z、0—9。
說明:search函數是re模塊裏面的,第一個參數就是原子,第二個參數是需要解析的字符串。
s = "JAVAandPython"
# 普通字符作爲原子
pattern = "and"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(4, 7), match='and'>
說明:re.research返回的是一個match對象
** 2.非打印字符作爲原子:**
非打印字符,是一些在字符串中的格式控制符號,例如空格、回車及製表符號等。例如下表所示列出了正則表達式中常用的非打印字符及其含義。
# 非打印字符作爲原子
s = '''JAVAand
Python
'''
pattern = "\n"
m = re.search(pattern, s)
print(m)
說明:這裏我們使用了三引號來進行換行書寫,s中是存在一個\n的
輸出結果:
<_sre.SRE_Match object; span=(7, 8), match='\n'>
** 3.通用字符作爲原子**
上面我們說的普通字符和非打印字符都是一個原子匹配一個字符,而通用字符是匹配一類字符,例如我們匹配數字時,不是匹配一個而是匹配這一類。
下面我給大家列舉出一些:
\w:包含字母,數字,下劃線
\W:除了字母,數字,下劃線之外的
\d:十進制的數字
\D:除十進制的數字
\s:空白字符
\S:除空白字符
# 通用字符作爲原子
s = 'JAVAand666python'
pattern = "\d\d\d\w"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(7, 11), match='666p'>
** 4.原子表:**
使用原子表“[]”就可以定義一組彼此地位平等的原子,且從原子表中僅選擇一個原子進行匹配。
# 原子表
s = 'JAVAand666python'
pattern = "and[1234567]"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(4, 8), match='and6'>
其實質就是從[]中選取符合原字符串的元素來進行匹配。
****3******** / 正則表達式之“元字符”/ ****
what is 元字符?所謂的元字符就是正則表達式中一些含有特殊意義的字符,如下表:
是不是看了之後還是有點懵逼?接下來,我給大家用代碼一一實現一下
1. “ . ” 除了換行符外的任意一個字符
# 元字符 . 除了換行外任意一個字符
s = 'JAVAand666python'
pattern = "JAVA."
m = re.search(pattern, s)
print(m)
pattern = "JAVA..."
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 5), match='JAVAa'>
<_sre.SRE_Match object; span=(0, 7), match='JAVAand'>
2. ^ 匹配輸入字符串的開始位置
s = 'JAVAand666python'
pattern = "^JAVA."
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 5), match='JAVAa'>
3. $ 輸入字符串的結束位置
s = 'JAVAand666python'
pattern = ".python$"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(9, 16), match='6python'>
- 匹配前子表達式的任意次
- 匹配前子表達式的1次或者多次
? 匹配前子表達式的0次或者1次
s = 'JAVAand666python'
pattern = "JAVA.*"
m = re.search(pattern, s)
print(m)
s = 'JAVAand666python'
pattern = "JAVA.+"
m = re.search(pattern, s)
print(m)
s = 'JAVAand666python'
pattern = "JAVA.?"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 16), match='JAVAand666python'>
<_sre.SRE_Match object; span=(0, 16), match='JAVAand666python'>
<_sre.SRE_Match object; span=(0, 5), match='JAVAa'>
5.{n} 匹配前子表達式恰好出現n次
** {n,} 匹配前子表達式至少出現n次**
** {n,m} 匹配前子表達式至少出現n次,至多出現m次**
s = 'JAVAanddddddd666python'
pattern = "JAVAand{3}"
m = re.search(pattern, s)
print(m)
s = 'JAVAanddddddd666python'
pattern = "JAVAand{3,}"
m = re.search(pattern, s)
print(m)
s = 'JAVAanddddddd666python'
pattern = "JAVAand{3,5}"
m = re.search(pattern, s)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 9), match='JAVAanddd'>
<_sre.SRE_Match object; span=(0, 13), match='JAVAanddddddd'>
<_sre.SRE_Match object; span=(0, 11), match='JAVAanddddd'>
OK,上面幾個是比較常見的元字符。
****4********/ 正則表達式之“模式修正符” / ****
雖然都說正則很難,其實基礎上也不是特別難,只是大部分的東西需要死記硬背,接下來我們來扯一下模式修正符,這個非常簡單,就幾個簡單的字母標點,但是也是需要我們記住的。
首先還是跟大家講下模式修正符是個啥,它就是通過一些特定的符號去改正正則表達式的含義,從而達到一些特定的效果而且我沒進行模式修正是不要去改變正則表達式的。
下表就是一些模式修正符:
這裏面比較重要的就是 I M S ,下面我就簡單給大家用代碼展示一個:
import re
s = "JAVAandPython666666"
pattern = 'java'
# 這裏的第三個參數就是調用了我們的模式修正符,其他的也是一樣的使用
m = re.search(pattern, s, re.I)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 4), match='JAVA'>
從上面的代碼和輸出結果可以看出我們通過re.I 忽略掉了大小寫。
再來看一個:
s = '''123java
asdasd
'''
pattern = '123.+'
# 這裏的第三個參數就是調用了我們的模式修正符,其他的也是一樣的使用
m = re.search(pattern, s, re.S)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 15), match='123java\nasdasd\n'>
從結果中,我們可以看到它把\n也打印出來了。
****5******** / 貪婪模式和懶惰模式 /****
其實從字面意思上就可以看出,“貪婪模式”就是儘可能多的匹配,“懶惰模式”就是儘可能少的匹配。可能大家還是不知道這是個啥,還是直接上代碼吧。
我們首先看一下貪婪模式:
s = '123JAVAandpypyPython'
pattern = '123.*py'
m = re.search(pattern, s, re.I)
print(m)
我們來看看輸出結果:
<_sre.SRE_Match object; span=(0, 16), match='123JAVAandpypyPy'>
我們從代碼和輸出結果分析,可以看到它直到最後一個py才停止
我們再來看一下懶惰模式:
s = '123JAVAandpypyPython'
pattern = '123.*?py'
m = re.search(pattern, s, re.I)
print(m)
輸出結果:
<_sre.SRE_Match object; span=(0, 12), match='123JAVAandpy'>
可以看到它匹配到第一個py時就停止了
總結:其實大家都可以發現,懶惰模式和貪婪模式就是一個問號的差別,貪婪模式是“.”,懶惰模式是“.?**”。貪婪模式就是會一直“吃”到底,懶惰模式就是“吃”到第一個就不吃了,按照這樣分析,可以發現貪婪模式所得到的結果是比較模糊的而懶惰模式得到的結果更加的精確。
****6******** / 正則表達式的函數 / ****
接下來我們來看一下正則中的函數,這個是十分重要的。我就直接上代碼。
import re
# 以下正則分成了兩個小組,以小括號爲單位
s = r'([a-z]+) ([a-z]+) ([a-z]+) ([a-z]+)'
# s.I表示忽略大小寫
pattern = re.compile(s, re.I)
# match -從頭開始匹配,但是search可以從任意處匹配
m = pattern.match("Hello World Kuls yes qweqwe")
# group(0)表示返回匹配成功的整個子串
s = m.group(0)
print(s)
# span(0)返回的是匹配成功的整個子串的跨度
a = m.span(0)
print(a)
# group(1)表示第一個匹配成功的子串
s = m.group(1)
print(s)
# span(1)表示第一個匹配成功的子串跨度
a = m.span(1)
print(a)
# groups()等價於group(1),group(2)
s = m.groups()
print(s)
其實我在代碼裏面給大家講解了每一個函數的作用,但是我還是把它扯出來吧,防止大家沒看到。
match -從頭開始匹配,但是search可以從任意處匹配
group(0)表示返回匹配成功的整個子串
span(0)返回的是匹配成功的整個子串的跨度
group(1)表示第一個匹配成功的子串
span(1)表示第一個匹配成功的子串跨度
groups()等價於group(1),group(2)
整個輸出的結果也給大家看看:
Hello World Kuls yes
(0, 20)
Hello
(0, 5)
('Hello', 'World', 'Kuls', 'yes')
另外還有兩個比較重要的函數findall和finditer,兩者相比,findall是最常用的。
import re
s = r'\d+'
# 全局匹配
pattern = re.compile(s)
m = pattern.findall("i am 18 years old and 185 high")
print(m)
# finditer
m = pattern.finditer("i am 18 years old and 185 high")
for i in m:
print(i.group())
輸出結果:
['18', '185']
18
185
可以看到findall返回的是一個list列表
****/ 一些常用的正則實例 /****
這裏給大家準備了一些經常用的正則實例,大家可以收藏收藏。
Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$
手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份證號(15位、18位數字):^\d{15}|\d{18}$
IP地址:\d+.\d+.\d+.\d+ (提取IP地址時有用)
中文字符的正則表達式:[\u4e00-\u9fa5]