Python 正則處理_re模塊

正則表達式

動機

  • 文本處理成爲計算機常見工做之一
  • 對文本內容搜索,定位,提取是邏輯比較複雜的工做
  • 爲了快速方便的解決上述問題,產生了正則表達式技術

定義

文本的高級匹配模式, 提供搜索, 替換, 本質由字符和特殊符號構成的字符串,python

這個字符串即爲正則表達式正則表達式

匹配原理

經過普通字符和特殊含義的字符串, 來組成字符串,ide

用以描述必定的字符串規則, 好比重複, 位置, 來表達一種特定類型的字符串, 進而匹配函數

正則字符

通用

 0 - 9   匹配全部字符
 a - z   匹配全部小寫字母
 A - Z   匹配全部大寫字母
 A-Za-z  匹配全部字母

字符

.       換行符之外的任意
\w      數字, 字母, 下劃線, 漢字    [a-z]
\s      空格
\d      數字  [0-9]
\b      單詞邊界    (數字,字母,下劃線,漢字 與 其餘字符交界位置)
\W      非 數字, 字母, 下劃線, 漢字   [^a-z]
\S      非 空格
\D      非 數字    [^0-9]
\B      非 單詞邊界
\n      換行符
\t      製表符
^       開始位置
$       結束位置
|       或 (匹配上即不在匹配,須要 長的放在前面 例如 abc|ab )

量詞

*       0~n次+       1~n次
?       0~1次
{n}     n次
{n,}    n或 n+次
{n,m}   n~m 次

字符集

[]      匹配字符組中的字符
[^]     匹配除了字符中的全部字符

分組

()      對總體進行 量詞約束   ---> \1 \2 \3 進行位置選擇
(?:)    取消分組優先

(?P<name>pattern)      命名分組   ----> \g<name1> \g<name2> 進行命名選擇

注意點spa

  • 一個正則中能夠存在多個分組, 且分組能夠嵌套
  • 做用前提是總體的表達式能被匹配到內容才能夠
  • 未命名分組和命名分組是能夠同時存在的, 未命名分組按照從外到內, 從左到右按照位置來用索引來命名
  • 分組不要重疊, 且最好不要嵌套, 假若出現說明設計存在巨大缺陷

轉義

\       被轉義前加反斜線表示 匹配這一字符而不是用做正則表達式來處理
r''     python 對字符串的不轉義須要 用 r 來表示, 減去書寫的麻煩

 實例解析設計

# r""
# s = "\\hello"
# print(re.findall("\\\\\\w+", s))
# print(re.findall(r'\\\w+', s))

"""
python 字符串      --> 正則      --> 目標字符串
"\\$\\d+"           \$\d+           "$100"
r"\$\d+"            \$\d+           "$100"
* 爲避免特殊字符串在字符串中使用時轉義的麻煩, 使用 raw 字符串來表達正則表達式
"""

總結

匹配單個字符

. [] [^] \d \D \w \W \s \S

匹配重複

* + ? {n} {n,m}

匹配位置

^ $ \A \Z \b \B

其餘

| () \

貪婪 / 非貪婪匹配

  • 默認 貪婪匹配 , 儘量的日後匹配更多的內容
  • 加 ? 改成 非貪婪匹配, 懶惰模式, 知足條件後不日後匹配更多內容
  • 主要影響到的是重複匹配的操做符 * + ? {n} {n,m}
# 非貪婪匹配的運用
# s = "ashb, asjdlab, asdadb"
# print(re.findall(r"a.*b", s))   # ['ashb, asjdlab,asdadb']
# print(re.findall(r"a.*?b", s))  # ['ashb', 'asjdlab', 'asdadb']

匹配原則

  • 正確性     正確的匹配出目標字符串
  • 精準性     除了目標內容, 儘量不要存在多餘內容
  • 全面性     儘量對目標字符串考慮全面, 作到不遺漏

Python re模塊使用

compile

regex = compile(pattern,flags=0)

功能  生成正則表達式對象code

參數 對象

   pattern 正則表達式blog

  flags 功能標識,擴展正則匹配功能索引

返回值  正則對象

compile對象屬性

  • flags : flags值
  • pattern : 正則表達式
  • groups : 子組數量
  • groupindex : 捕獲組名與組序號的字典

findall

re.findall(pattern,string,flags=0)

功能  經過正則表達式匹配目標字符串內容

參數

  pattern 正則表達式

  string 目標字符串

返回值  

   返回匹配到的內容列表

    若是正則表達式存在 子組 則只返回 子組對應的內容

sub

re.sub(pattern,replace,string,max,flags=0)

功能  使用指定字符串替換正則表達式匹配內容

參數  

  pattern 正則

  replace 指定字符串

  string 目標字符串

  max 最多替換幾處,默認所有替換

返回值  替換後的字符串

subn

re.subn() 

功能參數 同sub,

返回值 多一個實際替換個數

finditer

re.finditer(pattern,string,flags=0)

功能  使用正則表達式匹配目標內容

參數  

  pattern 正則

  string 目標字符串

返回值   迭代對象

fullmatch

re.fullmatch(pattern,string,flags=0)

功能  徹底匹配某個目標字符串

參數  

  pattern 正則

  string 目標字符串

返回值  匹配內容match object

match

re.match(pattern,string,flags=0)

功能  匹配某個目標字符串開始位置

參數

  pattern 正則

  string 目標字符串

返回值  匹配內容match object

match 對象

屬性

pos   匹配的目標字符串開始位置
endpos  匹配的目標字符串結束位置
re     正則表達式
string  目標字符串
lastgroup  最後一組的名稱
lastindex  最後一組的序號

方法

span()  獲取匹配內容的起止位置
start() 獲取匹配內容的開始位置
end()   獲取匹配內容的結束位置
groupdict()  獲取捕獲組字典,組名爲鍵,對應內容爲值
groups() 獲取子組對應內容
group(n = 0)

功能  獲取match對象匹配內容

參數  

  默認爲0表示獲取整個match對象內容

  若是是序列號或者組名則表示獲取對應子組內容

返回值  匹配字符串

import re
import sys

port = sys.argv[1]

f = open('1.txt')

# 找到端口所在的對應段落
while True:
    data = ''
    for line in f:
        if line != '\n':
            data += line
        else:
            break
    if not data:
        print("No PORT")
        break

    # 經過首單詞比對是否爲目標段
    try:
        PORT = re.match(r'\S+', data).group()
    except Exception:
        continue
    if port == PORT:
        # pattern=r"[0-9a-f]{4}\.[0-9a-f]{4}\.[0-9a-f]{4}"
        pattern = r"address is ((\d{1,3}\.){3}\d{1,3}/\d+|Unknown)"
        address = re.search(pattern, data).group(1)
        print(address)
        break

f.close()
找到端口所在的對應段落

search

re.search(pattern,string,flags=0)

功能  匹配目標字符串第一個符合內容

參數  

  pattern 正則

  string 目標字符串

返回值  匹配內容match object

flags

擴展豐富正則表達式的匹配功能

可調用的函數

re.compile,re.findall,re.search....

經常使用 flag

A == ASCII  元字符只能匹配ascii碼
I == IGNORECASE  匹配忽略字母大小寫
S == DOTALL  使 . 能夠匹配換行
M == MULTILINE  使 ^  $能夠匹配每一行的開頭結尾位置
X == VERBOSE  爲正則添加註釋

使用多個flag

flags = re.I | re.A

實例

import  re 

# 只匹配ascii字符
# regex = re.compile(r'\w+',flags=re.A)

# 忽略字母大小寫
# regex = re.compile(r'[A-Z]+',flags=re.I)

# . 能夠匹配換行
# regex = re.compile(r'.+',flags=re.S)

# 匹配每一行開始位置
# regex = re.compile(r'^北京',flags=re.M)

# 爲正則添加註釋
pattern = r'''[A-Z][a-z]* #匹配第一個單詞
\s+\w+\s+ #匹配空行和第二個單詞
\w+ #匹配漢字
'''
regex = re.compile(pattern,flags=re.X)

s = '''Welcome to
北京
'''
l = regex.findall(s)
print(l)
flag 實例

 split

split(pattern, string, maxsplit=0, flags=0)

功能  實現對字符串的正則切割, 能夠進行多個分隔符進行切割

參數  正則, 被切割字符串, 保留個數, flag 

import re

s = "sda.sda'sda/sda1adsa-ada.sad"
print(re.split("[./'-]+", s))
# ['sda', 'sda', 'sda', 'sda1adsa', 'ada', 'sad']
import re

s = "sda.sda'sda/sda1adsa-ada.sad"
print(re.split("[./'-]+", s, maxsplit=3))
# ['sda', 'sda', 'sda', 'sda1adsa-ada.sad']
相關文章
相關標籤/搜索