1. 程式人生 > >史上最詳細的正則表示式教程

史上最詳細的正則表示式教程

正則表示式

正則表示式的作用:

在實際開發過程中經常會有查詢符合某些複雜規則的字串的需要,比如:郵箱、圖片地址、手機號碼等,這時候想匹配或者查詢符合某些規則的字串就可以使用正則表示式了。

正則表示式概念

正則表示式就是記錄文字規則的程式碼

正則表示式的特點
正則表示式的語法很令人頭疼,可讀性差
正則表示式通用行很強,能夠適用於很多程式語言
re模組的使用過程

在Python中需要通過正則表示式對字串進行匹配的時候,可以使用一個模組,名字為re

    # 匯入re模組
    import re

    # 使用match方法進行匹配操作
result = re.match(正則表示式,要匹配的字串) # 如果上一步匹配到資料的話,可以使用group方法來提取資料 result.group()

注意:re.match() 根據正則表示式從頭開始匹配字串資料

開始進入正題

匹配單個字元

程式碼 功能
. 匹配任意1個字元(除了\n)
[ ] 匹配[ ]中列舉的字元
\d 匹配數字,即0-9
\D 匹配非數字,即不是數字
\s 匹配空白,即 空格,tab鍵
\S 匹配非空白
\w 匹配非特殊字元,即a-z、A-Z、0-9、_、漢字
\W 匹配特殊字元,即非字母、非數字、非漢字
# . 匹配任意1個字元(除了\n)
# [ ]   匹配[ ]中列舉的字元[ab456c][a-z]
# \d    匹配數字,即0-9
# \D    匹配非數字,即不是數字
# \s    匹配空白,即 空格,tab鍵\t,\n
# \S    匹配非空白
# \w    匹配單詞字元,即a-z、A-Z、0-9、_,國家的文字
# \W    匹配非單詞字元

# 匹配任意一個數字
# 使用\d
# 判斷使用者是否輸入的是速度與激情繫列
import re

# print(re.match("速度與激情\d", "速度與激情2"
).group()) # print(re.match("速度與激情\d", "速度與激情0").group()) # print(re.match("速度與激情\d", "速度與激情9").group()) # print(re.match("速度與激情\d", "速度與激情a").group()) # 使用[] # 格式1:[單個值,...] # 判斷使用者只想看1,4,8的速度與激情 # print(re.match("速度與激情[148]", "速度與激情1").group()) # print(re.match("速度與激情[148]", "速度與激情4").group()) # print(re.match("速度與激情[148]", "速度與激情8").group()) # print(re.match("速度與激情[148]", "速度與激情9").group()) # 格式2:[範圍,...] # 判斷使用者只看18的速度與激情 # print(re.match("速度與激情[12345678]", "速度與激情1").group()) # print(re.match("速度與激情[12345678]", "速度與激情8").group()) # print(re.match("速度與激情[1-8]", "速度與激情2").group()) # print(re.match("速度與激情[1-8]", "速度與激情8").group()) # # print(re.match("速度與激情[1-8]", "速度與激情9").group()) # 格式3:[數字字元] # 判斷使用者輸入的速度與激情18或者速度與激情a-h # # print(re.match("速度與激情[1-8]", "速度與激情8").group()) # print(re.match("速度與激情[a-h]", "速度與激情a").group()) # print(re.match("速度與激情[a-h]", "速度與激情h").group()) # print(re.match("速度與激情[a-h]", "速度與激情e").group()) # print(re.match("速度與激情[1-8a-h]", "速度與激情a").group()) # print(re.match("速度與激情[1-8a-h]", "速度與激情8").group()) # 使用\w 即a-z、A-Z、0-9、_這個範圍太廣,不要輕易用,漢字也可以匹配,其他的國家的語言也可以匹配 # 匹配的單詞字元 # 判斷使用者輸入包含速度與激情 # print(re.match("速度與激情\w", "速度與激情8").group()) # print(re.match("速度與激情\w", "速度與激情a").group()) # print(re.match("速度與激情\w", "速度與激情z").group()) # print(re.match("速度與激情\w", "速度與激情A").group()) # print(re.match("速度與激情\w", "速度與激情Z").group()) # print(re.match("速度與激情\w", "速度與激情_").group()) # print(re.match("速度與激情\w", "速度與激情好").group()) # print(re.match("速度與激情\w", "速度與激情あなたのことが好きです").group()) # # 使用\s # --匹配空白字元 # --空格 或者 tab(\t),\n換行 # --判斷使用者速度與激情 8 # print(re.match("速度與激情\s8", "速度與激情 8").group()) # print(re.match("速度與激情\s8", "速度與激情\t8").group()) # print(re.match("速度與激情\s8", "速度與激情\n8").group()) # # --大寫是所有小寫的非******* # .匹配任意1個字元(除了\n) # --匹配任意的字元 # --判斷包含速度與激情字串的 # print(re.match("速度與激情.", "速度與激情\tadf").group()) # print(re.match("速度與激情.", "速度與激情\nadf").group())
匹配多個字元的相關格式
程式碼 功能
* 匹配前一個字元出現0次或者無限次,即可有可無
+ 匹配前一個字元出現1次或者無限次,即至少有1次
? 匹配前一個字元出現1次或者0次,即要麼有1次,要麼沒有
{m} 匹配前一個字元出現m次
{m,n} 匹配前一個字元出現從m到n次
# -- 匹配的規則
# 字元        功能
# *     匹配前一個字元出現0次或者無限次,即可有可無
# +     匹配前一個字元出現1次或者無限次,即至少有1次
# ?     匹配前一個字元出現1次或者0次,即要麼有1次,要麼沒有
# {m}       匹配前一個字元出現m次  \d{3}
# {m,n} 匹配前一個字元出現從m到n次  \d{4,6}

# 使用  型別{}
# 用來表示一個字元出現多少次
# 匹配速度與激情1,速度與激情12
import re

# print(re.match("速度與激情\d", "速度與激情1").group())
# print(re.match("速度與激情\d\d", "速度與激情12").group())
# print(re.match("速度與激情\d{1,2}", "速度與激情12").group())
# print(re.match("速度與激情\d{1,2}", "速度與激情1").group())


# 匹配手機號11位

# print(re.match("\d{11}", "12345678901").group())

# 判斷電話號碼是否021 - 開頭的後面8位電話號碼
# 例: 021 - 12345678
# 判斷電話號

# print(re.match("021-\d{8}", "021-12345678").group())


# 使用?
# 用來表示有一個字元或者沒有字元
# 使用者輸入的電話號碼有時有'-'有時沒有
# 例:02112345678 或者  021-12345678

# print(re.match("021\d{8}", "02112345678").group())
# print(re.match("021-\d{8}", "021-12345678").group())
# print(re.match("021-?\d{8}", "021-12345678").group())
# print(re.match("021-?\d{8}", "02112345678").group())
#
#



# 有些地方是三位電話號碼開頭,有些是四位電話號碼開頭
# 0571-8123456
# 021-12345678

# print(re.match("\d{3,4}-?\d{7,8}", "0571-8123456").group())
# print(re.match("\d{3,4}-?\d{7,8}", "021-12345678").group())

# *
# 表示0或者無限次
# 匹配一段文字或者沒有輸入文字

str = """今天天氣不錯
我們可以出去運動一下!

"""

# print(re.match(".*", str).group())
print(re.match(".*", str, re.S).group())  # re.S這個就是跟.*配合在一起讓我們的真正的所有的都能匹配

# +
# 表示至少一次,不能為空
print(re.match(".*", "").group())
print(re.match(".+", " ").group())
匹配開頭和結尾的正則表示式
程式碼 功能
^ 匹配字串開頭
$ 匹配字串結尾
[^指定字元] 表示除了指定字元都匹配
# [^字元]這個是固定的一個語法,這個意思就是非
# 場景[email protected] [email protected],我們想取到第一個郵箱
# 如果寫字串有可能會有錯,他會去匹配一個字串出錯
import re

str = "hello@163.com hello@163.com"
print(re.match(".{4,20}@163\.com", str).group())

print(re.match("[^@]+@163\.com", str).group())

# [^字元]字元  非字元

print(re.match("[^bc]", "bc"))
匹配分組相關正則表示式
程式碼 功能
| 匹配左右任意一個表示式
(ab) 將括號中字元作為一個分組
\num 引用分組num匹配到的字串
(?P) 分組起別名
(?P=name) 引用別名為name分組匹配到的字串
# | 相當於python中的or
#   案例:匹配出163或者126的郵箱
import re

str = "[email protected]"

# print(re.match(".{4,20}@(163|126)\.com", str).group())

# ()還可以單獨取出匹配的某一部分資料
#   案例:取出郵箱的型別(只要163,126),後期可以編計使用者那個郵箱用的多

# print(re.match(".{4,20}@(163|126)\.com", str).group(0))
# print(re.match("(.{4,20})@(163|126)\.com", str).group(1))
# print(re.match("(.{4,20})@(163|126)\.com", str).group(2))
# print(re.match("(.{4,20})@((163|126)\.com)", str).group(2))



# \num用來取第幾組用()包裹的資料  \1取第一個內部的括號位置的值
# 格式(xxx)\1 :\1表示獲取(xxx)的值
# 案例<html>hh</html>  # 這個一定是有字母,開始跟結束的字母必須一樣

# str_data = "<html>hh</html> "
# print(re.match("<([a-zA-Z]+)>.*</\\1>", str_data).group())



# 案例<html><body>hh</body></html>
str_data = "<html><body>hh</body></html>"
# print(re.match("<([a-zA-Z]+)><([a-zA-Z]+)>.*</\\2></\\1>", str_data).group())


# 使用別名給分組取別名,瞭解一下
# 格式:(?P<別名>xxx)(?P=別名)
# 案例<html><body>hh</body></html>
# 提示問題沒錯
print(re.match("<(?P<name1>[a-zA-Z]+)><(?P<name2>[a-zA-Z]+)>.*</(?P=name2)></(?P=name1)>", str_data).group())

注意:(分組資料):分組數是從左到右的方式進行分配的

正則的高階用法
程式碼 功能
search 不會從頭開始匹配,只要匹配到資料就結束
findall 查詢結果集
sub 將匹配到的資料進行替換
split 根據匹配進行切割字串,並返回一個列表
# 查詢結果
#   search 不會從頭開始匹配,只要匹配到資料就結束
#   案例:匹配出文章閱讀的次數中的次數
#   資料:"閱讀次數為 9999"

import re

# print(re.search("\d+", "閱讀次數為 9999").group())



# 查詢結果集
# findall
# 案例: 統計出python、c、c + +相應文章閱讀的次數
# 資料: "python = 9999, c = 7890, c++ = 12345"

# print(re.findall("\d+", "python = 9999, c = 7890, c++ = 12345"))



# 字串切割
# split
# 切割字串“info:xiaoZhang 33 shandong”, 根據:或者空格
# print(re.split(":|\s", "info:xiaoZhang 33 shandong"))


# 替換資料
# sub
# 案例: 將匹配到的閱讀次數換成998
# 資料: "python = 997"

# re.sub("替換的匹配","想替換成的內容","被替換的內容")

str_data = "python = 10000"


# 生成一個新的字元
# new_data = re.sub("\d+", "998", str_data)
#
# print(new_data)
# print(str_data)

# 通過函式來修改值

def change_value(match):
    # 通過匹配的物件拿到對應的值
    value = match.group()
    # 值加1
    count_str = int(value) + 1

    return str(count_str)  # 必須返回字串


print(re.sub("\d+", change_value, str_data))
python貪婪和非貪婪

Python裡數量詞預設是貪婪的(在少數語言裡也可能是預設非貪婪),總是嘗試匹配儘可能多的字元;非貪婪則相反,總是嘗試匹配儘可能少的字元。

r 的作用
  • Python中字串前面加上 r 表示原生字串,資料裡面的反斜槓不需要進行轉義,針對的只是反斜槓

  • Python裡的原生字串很好地解決了這個問題,有了原生字串,你再也不用擔心是不是漏寫了反斜槓,寫出來的表示式也更直觀。

>>> mm = "c:\\a\\b\\c"
>>> mm
'c:\\a\\b\\c'
>>> print(mm)
c:\a\b\c
>>> re.match("c:\\\\",mm).group()
'c:\\'
>>> ret = re.match("c:\\\\",mm).group()
>>> print(ret)
c:\
>>> ret = re.match("c:\\\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\a",mm).group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>

建議: 如果使用使用正則表示式匹配資料可以都加上r,要注意r針對的只是反斜槓起作用,不需要對其進行轉義

>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a

相關推薦

表示式

正則表示式——古老而又強大的文字處理工具。僅用一段簡短的表示式語句,就能快速地實現一個複雜的業務邏輯。掌握正則表示式,讓你的開發效率有一個質的飛躍。 正則表示式經常被用於欄位或任意字串的校驗,比如下面這段校驗基本日期格式的JavaScript程式碼: var date = "1994

馬上收藏!表示式合集

一.校驗數字 數字:^[0-9]*$ n位的數字:^\d{n}$ 至少n位的數字:^\d{n,}$ m-n位的數字:^\d{m,n}$ 零和非零開頭的數字:^(0|[1-9][0-9]*)$ 非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*

移植QT5.6到嵌入式開發板(詳細的QT移植教程

文件傳輸 嵌入式環境 ubun 導致 字庫 etc -a led fill 目前網上的大多數 QT 移植教程還都停留在 qt4.8 版本,或者還有更老的 Qtopia ,但是目前 Qt 已經發展到最新的 5.7 版本了,我個人也已經使用了很長一段時間的 qt5.6 for

黃聰:詳細的kali安裝教程沒有之一

ner 沒有 操作系統 你是 著作權 如圖所示 鏈接 class 區域 首先在vm裏面新建虛擬機,直接選擇典型,然後下一步。 1 2 然後到了這一步,選擇中間的安裝程序光盤鏡像文件,然後去文件裏面

詳細的Vmware安裝教程(一)-建立Linux虛擬機器

本文將演示如何使用Vwmare workstation軟體建立Linux虛擬機器,通過學習,我們將可以按照自己下需求,來建立一個安裝Linux作業系統(Centos)的虛擬機器,虛擬機器的CPU、硬碟、網絡卡、記憶體等硬體都可以根據需要進行定製。 1. 準備Host機器(

超級詳細表示式教程

/ 順斜槓是表示表示式的開始和結束的“定界符” \ 反斜槓是表示轉義字元 /^[^\?]+\??/ : ^表示匹配文字的開頭,[]表示匹配滿足內部條件的字元,[]裡面的^\?表示除了?以外的任意字元,[]後面的+表示匹配的次數為1次或大於1次,一直到?才匹配結束,\?表示?字元,

詳細表示式教程

正則表示式 正則表示式的作用: 在實際開發過程中經常會有查詢符合某些複雜規則的字串的需要,比如:郵箱、圖片地址、手機號碼等,這時候想匹配或者查詢符合某些規則的字串就可以使用正則表示式了。 正則表示式概念 正則表示式就是記錄文字規

詳細的js日期表示式分享

最簡單的正則 如 : /d{4}-/d{2}-/d{2} 但是實際情況卻不是那麼簡單,,要考慮,有效性和閏年等問題..... 對於日期的有效範圍,不同的應用場景會有所不同。MSDN中定義的DateTime物件的有效範圍是:0001-01-01 00:00:00到9999

XX-NET詳細完整教程

偽造 不用 app 分享圖片 AS 版本 firefox 配置過程 自動切換 前言   XX-NET,系GAE類代理,即通過可用Google ip連接Google App Engine項目,然後把所有tcp請求發送給Google App Engine,最終實現科學式網絡的

詳細的爬蟲教程,Python採集全網受歡迎的 500 本書!

      想看好書?想知道哪些書比較多人推薦,最好的方式就是看資料,接下來用 Python 爬取噹噹網五星圖書榜 TOP500 的書籍,或許能給我們參考參考! Python爬取目標   爬取噹噹網前500本受歡迎的書籍 解析書籍名稱

詳細完全的ipython使用教程,Python使用者必備!——ipython系列之二

宣告:本文承接前面一篇文章,ipython系列之一;另外,本文所指的ipython不是ipython notebook,ipython notebook已經被jupyter notebook所取代,不再叫ipython notebook了。 前面講解了ipython裡面的一些核心

詳細完全的ipython使用教程,Python使用者必備!——ipython系列之一

一、ipython簡介 關於什麼是ipython,本文就不加以介紹了,他是一個非常流行的python直譯器,相比於原生的python直譯器,有太多優點和長處,因此幾乎是python開發人員的必知必會。 1、ipython相比於原生的python有什麼優勢 (1) pyth

詳細git教程

閱讀目錄 題外話 雖然這個標題很驚悚,不過還是把你騙進來了,哈哈~各位看官不要著急,耐心往下看 Git是什麼 Git是目前世界上最先進的分散式版本控制系統。 SVN與Git的最主要的區別 SVN是集中式版本控制系統,版本庫是集中放在中央伺服器的,而

網站對接支付寶,微信支付介面詳細教程

聯絡qq:1104752746對接支付寶支付介面,官方文件已經寫的很清楚了,但是也有很多像我一樣的小白,第一次對接支付寶支付介面,會有些迷茫,所以我在此寫下這篇文章,給我和我一樣的同學,一點思路吧。三分鐘就可以申請介面實用小技巧QQ:1104752746支付寶個人即時到賬支付

歸併排序——詳細圖解教程!!!

題目大意:把n個數,分成若干份,然後每一份暴力排序一下,然後遞迴地合起來。 為什麼要這樣做?這樣有個球用? 核心問題就在於,每兩份之間你是怎麼合起來的。 我們舉個例子。 一個比較呆萌的思路就是,2二分插入,形成新的序列,再繼續用4插入。。。這樣的話,確實沒什麼球用。

詳細Python爬取電影教程,還不會那也是沒誰了

摘要: 作為小白,爬蟲可以說是入門python最快和最容易獲得成就感的途徑。因為初級爬蟲的套路相對固定,常見的方法只有幾種,比較好上手。選取網頁結構較為簡單的貓眼top100電影為案例進行練習。 重點是用上述所說的4種方法提取出關鍵內容。一個問題採用不同的解決方法有助於拓展思維,通過不斷練

如何玩轉F3D?詳細教程版本來了!

教你如何玩轉F3D。話不多說,進入正文。 首先,你需要科學上網,相信這個幣圈中人絕不陌生,韭菜芽們可以自行百度VPN。在此之前,我們要準備好如下三樣法寶:一臺已經科學上網的電腦,一個谷歌瀏覽器,和兩個網址。 下面跟著KK我們一步步來: 首先複製好網址,開啟谷歌瀏

Hadoop大資料元件安裝 詳細教程 手把手教會你安裝

Hadoop安裝--大資料元件安裝--史上最完整教程--手把手教會你安裝  ——徹底揭開大資料技術的面紗,讓小白徹底進入大資料技術領域 安裝的Hadoop的生態圈元件有如下幾個(以後會不斷補充完善起來了)。 (1)Hadoop(單機模式獨立,偽分散式偽分散式,全分散式全

個人網站對接支付寶,微信支付介面詳細教程

聯絡qq:785087203對接支付寶支付介面,官方文件已經寫的很清楚了,但是也有很多像我一樣的小白,第一次對接支付寶支付介面,會有些迷茫,所以我在此寫下這篇文章,給我和我一樣的同學,一點思路吧。三分鐘就可以申請介面實用小技巧QQ:785087203支付寶個人即時到賬支付

一步步教你搭建Android開發環境(有圖有真相)--“自吹自擂:詳細囉嗦、最新的搭建教程

宣告:轉摘請註明http://blog.csdn.net/longming_xu/article/details/28241045 前言:為什麼要寫這麼一篇文章?網上介紹Android開發環境搭建的文章一片一片的,我為什麼要自己”重複的去造輪子“呢?原因有三個:第一個