1. 程式人生 > >Python_基礎_(正表示式)

Python_基礎_(正表示式)

一,正則表示式

 普通的匹配都為完全匹配

正則表示式為模糊匹配

## 元字元

 

  . ^ $ * + ? {} [] () \

 

### .:一個點代表匹配一個字元
>>> re.findall("he..o","abchelloabc")
['hello']
>>>

### ^:在字串的開頭進行匹配,
>>> re.findall("^hello","ahello")
[]
>>> re.findall("^hello","helloabc")
[
'hello'] >>>

### $:以什麼進行結尾
>>> re.findall("hello$","abchello")
['hello']
>>>

### *:按著挨著的字元進行重複(0~無窮)
>>> re.findall("o*","helloworldoooooaooo")
['', '', '', '', 'o', '', 'o', '', '', '', 'ooooo', '', 'ooo', '']
>>>

### +:按著挨著的字元進行重複(1~無窮) 至少有一個,貪婪匹配
>>> re.findall("o+","helloworldoooooaooo") ['o', 'o', 'ooooo', 'ooo'] >>> >>> re.findall("hello+","helloworldoooooaooo") ['hello'] >>>

### ?:按著挨著的字元進行重複(1~0)    ,最多為1個
>>> re.findall("o?","helloworldoooooaooo")
['', '', '', '', 'o', '', 'o', '', '', ''
, 'o', 'o', 'o', 'o', 'o', '', 'o', 'o', 'o', ''] >>> >>> re.findall("hello?","helloworldoooooaooo") ['hello'] >>>

{}:可以表示前面三種的情況
    {0,} == *
    {1,} == +
    {0,1} == ?
    
    {6}表示可以重複6次
    {1,6}表示可以重複1~6中任意的次數

### 將貪婪匹配變成惰性匹配,
### 在原本*號的後面加上一個?,將貪婪匹配變成惰性匹配
>>> re.findall("hello*?","abchelloabc")
['hell']
>>>
>>> re.findall("hello+?","abchelloabc")
['hello']
>>>

# 元字符集[]
>>> re.findall("x[yz]","xyssssssxzjxpjjjj")
['xy', 'xz']
>>>
 
>>> re.findall("x[yzp]","xyssssssxzjxpjjjj")
['xy', 'xz', 'xp']
>>>


注:元字符集中的符號大多數為普通符號 如 *  + ?
### 元字符集中有特殊意義的為 - ^ \
### 一個星只匹配一個符號
>>> re.findall("g[e*x]","fefefalgeeexxxx")
['ge']
>>>

### []與-
#[a-z]匹配a~z中的一個元素
>>> re.findall("g[a-z]","feaafgua")
['gu']
>>>

>>> re.findall("g[a-z]*","feaafgua")
['gua']
>>>

### [0-9]匹配0~9
>>> re.findall("g[0-9]*","abcg123")
['g123']
>>>

### []與^與-
### 注:^表示的是非的意思
### 匹配非0~9的字元
>>> re.findall("g[^0-9]","feaafgua")
['gu']
>>>

### 匹配非a~z的字元
>>> re.findall("g[^a-z]*","feaafg4415ua")
['g4415']
>>> re.findall("g[^a-z]*","feaafg44s15ua")
['g44']
>>>

### 元字元轉義字元 \

### \d 匹配任何的十進位制數
>>> re.findall("\d","12+(23+34)")
['1', '2', '2', '3', '3', '4']
>>> re.findall("\d+","12+(23+34)")
['12', '23', '34']
>>>

### \D 匹配任何非數字字元
>>> re.findall("\D","12+(23+34)")
['+', '(', '+', ')']
>>>

### \s 匹配任何空白字元
>>> re.findall("\s","hello world")
[' ']
>>>

### \S 匹配任何非空白字元
>>> re.findall("\S","hello world")
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
>>> re.findall("\S+","hello world")
['hello', 'world']
>>>

### \w 匹配任何字母,數字字元    相當於a-z  A-Z  0-9
>>> re.findall("\w","hello world111")
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '1', '1', '1']
>>> re.findall("\w+","hello world111")
['hello', 'world111']
>>>

>>> re.findall("\w+","hello world111_+")
['hello', 'world111_']
>>>

### \W 匹配任何非數字,非字母字元
>>> re.findall("\W","abc123?._")
['?', '.']
>>>

 
 
### \b 匹配一個特殊字元邊界,比如空格 & # 
>>> re.findall(r"I\b","hello I am LIST")
['I']
>>>
>>> re.findall("I\\b","hello I am LIST")
['I']
>>>
### 元字元之|
|:俗稱管道符
>>> re.findall("ka|b","asdffka|b")
['ka', 'b']
>>> re.findall("ka|b","asdffkab")
['ka', 'b']
>>>

### 元字元之分組()
注:search()    # 匹配字串,只要匹配到一個就不再往下匹配
>>> re.findall("\d+","fadf55adfa85af58")
['55', '85', '58']

>>> re.search("\d+","fdfd58fdfd11df5df")
<_sre.SRE_Match object at 0x028EFA68>    # 得到的是一個物件
>>> re.search("\d+","fdfd58fdfd11df5df").group()    # 利用group得出結果
'58'
>>>

>>> re.search("[a-z]+","123hello123abc").group()
'hello'
>>>

   
### (?P<id>[a-z]+)自定義一個分組,分組名稱為id
>>> re.search("(?P<id>[a-z]+)","123hello123abc").group()
'hello'
>>>

>>> re.search("(?P<id>[a-z]+)\d","123hello123abc").group()
'hello1'
>>>

>>> re.search("(?P<id>[a-z]+)\d+","123hello123abc").group()
'hello123'
>>>

>>> re.search("(?P<id>[a-z]+)\d+","123hello123abc").group("id")
'hello'
>>>

## r

re.findall(r"I\b","hello I am LIST")

上方程式碼中 r 表示的作用:加上r表示對所處理的字元不做任何的轉義,因為Python在進行解釋時,會對轉義字元進行轉義,而re模組也會對轉義字元進行轉義,所以會照成干擾,加上r後,Python不對其進行轉義,直接讓re模組進行解釋

\\b:Python對程式進行解釋時,將其轉義為\b,而後re模組對其進行解釋,re表示式只能認為是 \b

r"\\b":Python對程式進行解釋時,不進行轉義,而直接給re模組進行處理

# 一種不使用 r 的方法
re.findall("c\\\\l")
python對其進行轉義,轉義成c\\l
# 而後re對其再次進行轉義,轉義成c\l
# 所以將\\\\轉義成\
>>> re.findall("I\\\\l","hello I am LI\lST")
['I\\l']
>>>
# 注:上方的結果為兩個反斜槓,因為返回到python中時又添加了一個,表示\

\. 表示一個普通點
\* 表示一個普通*

## re中常用的方法

#1
findall

#2
search

#3
match("a","abc").group()    # 用法與search,不同於match只取頭

#4
>>> re.split("[ab]","abcd")    # 先按a進行分割,得到''和'bcd',再將''和'bcd’按b進行分割
['', '', 'cd']

#5
sub替換,具有三個引數
>>> re.sub("\d+","A","hello1998World")    # 將其中的數字替換為A 
'helloAWorld'

>>> re.sub("\d","A","hello1998World")    # 將其中的每個數字替換為A
'helloAAAAWorld'

>>> re.sub("\d","A","hello1998World",2)        # 後加引數2,匹配前兩個數字
'helloAA98World'

#6
>>> re.subn("\d","A","hello1998World")        # 輸出匹配後的內容與匹配的次數
('helloAAAAWorld', 4)

#7
com = re.compile("\d")    
# 將要匹配的規則存到com中
# 可以重複使用com

>>> com = re.compile("\d")
>>> com.findall("dfadfd1fwe33adf")
['1', '3', '3']

#8
>>> re.finditer("\d+","efwerfqw1212rtfgwe4454")
<callable-iterator object at 0x03008170>
>>>
# 與findall區別是返回一個迭代器物件
# 好處:當處理大量資料是,不需要將所有的資料全部存放到記憶體中,而是存放到迭代器中
>>> ret = re.finditer("\d+","efwerfqw1212rtfgwe4454")
>>> next(ret).group()    # 用next讀取
'1212'
>>> next(ret).group()
'4454'
>>>

# 注注:當使用分組時,re預設會將括號中分組的內容優先拿出,如下所示
>>> re.findall("www\.(baidu|sina)\.com","www.baidu.com")
['baidu']

# 去優先順序:加上?:
>>> re.findall("www\.(?:baidu|sina)\.com","www.baidu.com")
['www.baidu.com']

 

# 補充
>>> re.findall("(abc)+","abcabcabc")    # 括號有優先順序,只顯示一個
['abc']
>>> re.findall("(?:abc)+","abcabcabc")    # 用?:取消優先順序
['abcabcabc']