正則

正則

概述:
正則表達式,Regular Expression,縮寫regex、regexp、RE
正則表達式是文本處理極為重要的技術,用它可以對字符串按照某種規則進行檢索、替換
1970年,Unix之父ken Thompson將正則表達式引入到Unix中文本編輯器ed和grep命令中,由此正則表達式普及開來
1980年后,perl語言對Henry Spencer編寫的庫,擴展了很多新的特性。1997年開始,Philip Hazel開發除了PCRE(perl compatible regular expressions),它被PHP和HTTPD等工具采用。
正則表達式應用極其廣泛,shell中處理文本的命令、各種高級編程語言都支持正則
分類:
  • BRE:基本正則表達式,grep sed vi等軟件支持。vim有擴展
  • ERE:擴展正則表達式,egrep(grep -E)、sed -r等
  • PCRE:幾乎所有高級語言都是PCRE的方言或變種。python從1.6開始使用SRE正則表達式引擎,可以認為是PCRE的子集,見模塊re

基本語法

元字符
  • . 匹配除換行符外任意一個字符
  • [abc]:字符集合,只能表示一個字符的位置,匹配所有包含的任意一個字符:[abc]匹配plain中的‘a’
  • [^abc]:字符集合,只能表示一個字符的位置,匹配除去集合內字符的任意一個字符:[abc]匹配plain中的‘p’、‘l’、‘i’、‘n’
  • [a-z]:字符范圍,也是一個集合,表示一個字符位置,匹配所包含的任意一個字符
  • [^a-z]:匹配除去集合內字符的任意一個字符
  • \b:匹配單詞的邊界:\bb在文本中找到單詞b開頭的b字符
  • \B:不匹配單詞的邊界:t\B包含t的單詞但是不以t結尾的t字符,如write
  • \d:[0-9]匹配一位數字
  • \D:[^0-9]匹配一位非數字
  • \s:匹配1位空白字符,包括換行符、制表符、空格
  • \S:匹配1位非空白字符
  • \w:匹配[a-zA-Z0-9_],包括中文的字
  • \W:匹配\w之外的字符
單行模式:
.可以匹配所有字符,包括換行符
^表示整個字符串的開頭,正則行尾
^表示整個字符串的開始,$表示整個字符串的結尾。開始指的是\n后緊接著下一個字符,結束指的是/n前的字符
  • 轉義:凡是在正則表達式中有特殊意義的符號,如果想使用它的本意,請使用\轉義。反斜杠自身,則使用\。\r,\n還是轉義后代表回車換行
重復
  • * :表示前面的正則表達式會重復0次或多次:e\w*單詞中有e然后后面非空白字符
  • +:表示前面的正則表達式重復至少1次
  • ?:表示前面的正則表達式會重復0次或1次
  • {n}:重復固定n次
  • {n,}:重復至少n次 {1,}等價于+ | {0,}等價于啊* | {0,1}等價于?
  • {n,m}:重復n到m次
  • x|y:匹配x或者y
  • 捕獲:
    • (pattern):使用小擴號指定一個子表達式,也叫分組。捕獲后會自動分配組從1開始可以改變優先級
    • \數字:匹配對應分組
    • (?:pattern):如果僅僅為了改變優先級,就不需要捕獲分組
    • (?\<name\>exp)、(?’name’exp):分組捕獲,但是可以name訪問分組python語法必須是(?P\<name\>exp)
  • 零寬斷言
    • (?=exp):斷言exp一定在匹配的右邊出現,也就是說斷言后面一定跟一個exp:f(?=oo)f后面一定有oo出現
    • (?<=exp):斷言exp一定出現在匹配的左邊,也就是說前面一定有個exp前綴:(?<=f)ood,ood前一定有f出現
  • 負向零寬斷言:
    • (?!exp):斷言exp一定不會出現在右側,也就是說斷言后面一定不是exp
    • (?>!exp):斷言exp一定不能出現在左側,也及時說斷言前面一定不能是exp:(?<!f)ood ood的左邊一定不是f</li>
  • (?#comment):注釋 例如:f(?=oo)(?#這個后斷言不捕獲)
分組和捕獲是同一個意思,能用簡單表達式,就不要用復雜的表達式
貪婪與非貪婪
  • 默認是貪婪模式,也就是說盡量匹配更長的字符串
  • 非貪婪模式很簡單,在重復的符號后面加一個?問好,就是盡量少匹配了
  • *?:匹配任意次,但盡可能少重復
  • +?:匹配至少一次,但盡可能少重復
  • ??:匹配0次或一次,但盡可能少重復
  • {n,}?:匹配至少n次,但盡可能少重復
  • {n,m}?:匹配至少n次,至多m次,但盡可能少重復
  • 引擎選項:
  • IgnoreCase:匹配時忽略大小寫。re.l/re.IGNORECASE
  • Singleline:單行模式:.可以匹配所有字符,包括\n。re.S/re.DOTALL
  • Multiline:多行模式:^行首、$行尾。re.M/re.MULTILINE
  • IgnorePatternWhitespace:忽略表達式中的空白字符,如果要使用空白字符用轉義,#可以用來左注釋。re.X/re.VERBOSE
練習:
匹配身份證號:
\d{10}[0-9]{2}([0-2]\d|3[01])\d{3}(\d|x)
Python的正則表達式
  • Python使用re模塊提供了正則表達式處理的能力
  • 常量:
    • re.M/re.MULTLINE:多行模式
    • re.S/re.DOTALL:單行模式
    • re.l/re.IGNORECASE:忽略大小寫
    • re.X/re.VERBOSE:忽略表達式中的空白字符
    • 使用|位或運算開啟多種選項
  • 方法:
    • 編譯:
      • re.compile(pattern,flags=0)
      • 設定flags,編譯模式,返回正則表達式對象regex
      • pattern就是正則表達式字符串,flags是選項。正則表達式需要被編譯,為了提高效率,這些編譯后的結果被保存,下次使用同樣的pattern的時候,就不需要再次編譯。
      • re的其他方法為了提高效率都調用了編譯方法,就是為了提速
        單次匹配:
    • re.match(pattern,string,flags=0)
    • regex.match(string,pos[,endpos])
    • match匹配從字符串的開頭匹配,regex對象match方法可以重設定開始位置和結束位置。返回match對象
    • re.search(pattern,string,flags=0)
    • regex.search(string[,pos[,endpos]])
    • 從頭搜索直到第一個匹配,regex對象search方法可以重設定開始位置和結束位置,返回match對象
    • re.fullmatch(pattern,string,flags=0)
    • regex.fullmatch(string[,pos[,endpos]])
    • 整個字符串和正則表達式匹配
全部匹配
* re.findall(pattren,string,flag=0)
* regex.findall(string[,pos[,endpos]])
* 對整個字符串,從左至右匹配,返回所有匹配項的列表
* re.finditer(pattern,string,flag=0)
* regex.finditer(string[,pos[,endpos]])
* 對整個字符串,從左至右匹配,返回所有匹配項,返回`迭代器`
* 注意:每次迭代返回的是match對象
#舉例:
In [43]: s = ”’bottle\nbag\nbig\napple”’
In [44]: for x in enumerate(s):
…: if x[0] % 8 == 0:
…: print()
…: print(x,end=”)
…: print(‘\n’)
(0, ‘b’)
(8, ‘a’)
(16, ‘p’)
In [45]: result = re.match(‘b’,s)#找不到第一個就不找了
In [46]: print(1,result)
1 <_sre.SRE_Match object; span=(0, 1), match=’b’>
In [47]: result = re.match(‘a’,s)#第一個沒找到就返回None
In [48]: print(2,result)
2 None
In [49]: result = re.match(‘^a’,s,re.M)#依然從頭找
In [50]: print(3,result)
3 None
In [51]: result = re.match(‘^a’,s,re.S)
In [52]: print(4,result)
4 None
#先編譯,然后使用正則表達式對象
In [53]: regex = re.compile(‘a’)
In [54]: result = regex.match(s)
In [55]: print(5,result)
5 None
In [56]: result = regex.match(s,15)#把索引15作為開始找
In [57]: print(6,result)
6 <_sre.SRE_Match object; span=(15, 16), match=’a’>
#search方法
In [3]: s
Out[3]: ‘bottle\nbig\nbag\napple’
In [4]: re.search(‘^b’,s)#掃描找到匹配的第一個位置
Out[4]: <_sre.SRE_Match object; span=(0, 1), match=’b’>
In [6]: re.search(‘^b\w+’,s)
Out[6]: <_sre.SRE_Match object; span=(0, 6), match=’bottle’>
In [7]: re.search(‘^b\w+’,s,re.M)
Out[7]: <_sre.SRE_Match object; span=(0, 6), match=’bottle’>
In [9]: result = re.compile(‘^b’,re.M)#提前編譯好再調用
In [10]: result.search(s)
Out[10]: <_sre.SRE_Match object; span=(0, 1), match=’b’>
In [11]: result.search(s,10,20)#提前編譯的可以使用pos,endpos
Out[11]: <_sre.SRE_Match object; span=(11, 12), match=’b’>
#fullmatch方法
In [12]: re.fullmatch(‘bag’,s)
In [13]: result = re.compile(‘bag’,re.M)
In [14]: result.fullmatch(s,7,10)#無返匹配結果
In [15]: s
Out[15]: ‘bottle\nbig\nbag\napple’
In [18]: result.fullmatch(s,11,14)#指定索引位置,要完全匹配,多少都不行。末尾是開區間
Out[18]: <_sre.SRE_Match object; span=(11, 14), match=’bag’>
#findall方法,全部匹配
In [19]: re.findall(‘^b’,s)#單行模式下,此處^不是詞首而是行首的意思
Out[19]: [‘b’]
In [20]: s
Out[20]: ‘bottle\nbig\nbag\napple’
In [21]: re.findall(‘^b’,s,re.M)#多行模式可以返回所有b開頭的行
Out[21]: [‘b’, ‘b’, ‘b’]
In [66]: re.findall(r’\bb\w+\b’,s)#單行模式匹配行中的多個單詞
Out[66]: [‘bottle’, ‘bag’, ‘big’]
In [64]: re.findall(‘b\w+’,s)
Out[64]: [‘bottle’, ‘bag’, ‘big’]
#finditer方法,全部匹配并返回生成器對象
In [68]: c = re.finditer(‘b\w+’,s)
In [69]: print(next(c))
<_sre.SRE_Match object; span=(0, 6), match=’bottle’>
In [70]: print(next(c))
<_sre.SRE_Match object; span=(7, 10), match=’bag’>
In [71]: print(next(c))
<_sre.SRE_Match object; span=(11, 14), match=’big’>
匹配替換
  • re.sub(pattern,replacement,string,count=0,flags=0)
  • regex.sub(replacement,string,count=0)
  • 使用pattern對字符串string進行匹配,對匹配項使用repl替換
  • replacement可以是string、bytes、function
  • re.subn(pattern,replacement,string,count=0,flags=0)
  • regex.subn(replacement,string,count=0)
  • 同sub返回一個元組(new_string,number_of_sub_made)
#sub舉例:
In [79]: s
Out[79]: ‘bottle bag big apple’
In [76]: re.sub(‘a’,’c’,s)
Out[76]: ‘bottle bcg big cpple’
In [77]: regex = re.compile(‘e’)
In [80]: regex.sub(‘mage’,s)
Out[80]: ‘bottlmage bag big applmage
#subn舉例:
In [82]: re.subn(‘b’,’Thunk’,s)
Out[82]: (‘Thunkottle Thunkag Thunkig apple’, 3)#返回元組及替換次數
字符串分割
字符串分割函數劣勢:不能指定多個字符串進行分割
  • re.split(pattern,string,maxsplit=0,flags=0)
  • re.split分割字符串
In [114]: s
Out[114]: ‘bottle \n ba|g \nbig’
In [115]: print(s.split())#字符串切割函數無法做到多分隔符分割
[‘bottle’, ‘ba|g’, ‘big’]
In [120]: re.split(‘[\se]’,s,re.M)#通過正則指定多分割符切割
Out[120]: [‘bottl’, ”, ”, ”, ‘ba|g’, ”, ‘big’]
In [121]: re.split(‘[\sb]’,s,re.M)
Out[121]: [”, ‘ottle’, ”, ”, ”, ‘a|g’, ”, ”, ‘ig’]
分組
  • 使用小擴號的pattrn捕獲的數據被放到了組group中
  • match、search函數可以返回match對象;findall返回字符串列表;finditer返回一個個match對象
  • 如果pattern中使用了分組,如果有匹配結果,會在match對象中
  • 1.使用group(N)方式返回對應分組,1-N是對應的分組,0返回整個匹配的字符串
  • 2.如果使用了命名分組,可以使用group(‘name’)的方式取分組
  • 3.也可以使用groups()返回所有分組
  • 4.使用groupdict()返回所有命名的分組
#group分組
In [137]: regex = re.compile(‘(b\w+)’)
In [138]: regex.match(s)
Out[138]: <_sre.SRE_Match object; span=(0, 6), match=’bottle’>
In [148]: regex.search(s).groups()#groups取出所有分組并返回元組
Out[148]: (‘bottle’,)
In [149]: regex.search(s).group()
Out[149]: ‘bottle’
In [152]: regex = re.compile(‘(b\w+)\s(?P<name2>b\w+)’)#定義分組名稱
In [153]: regex.search(s).group()
Out[153]: ‘bottle\nbag’
In [154]: regex.search(s).groups()
Out[154]: (‘bottle’, ‘bag’)
In [157]: regex.search(s).group(‘name2’)#調取名稱分組
Out[157]: ‘bag’
In [158]: regex.search(s).group(1)#索引分組
Out[158]: ‘bottle’
In [159]: regex.search(s).groupdict()#將分組轉換成字典
Out[159]: {‘name2’: ‘bag’}
#迭代:
In [167]: for x in result:
…: print(type(x),x,x.group(),x.group(‘name2’))
—————————————————————————
TypeError Traceback (most recent call last)
<ipython-input-167-2b12e049a45a> in <module>()
—-> 1 for x in result:
2 print(type(x),x,x.group(),x.group(‘name2’))
TypeError: ‘_sre.SRE_Match’ object is not iterable#match對象不可迭代
In [168]: type(result)
Out[168]: _sre.SRE_Match
In [169]: regex = re.compile(‘(?P<head>b\w+)’)
In [170]: result = regex.finditer(s)#生成一個可迭代對象
In [171]: for x in result:
…: print(type(x),x,x.group(),x.group(‘head’))
<class ‘_sre.SRE_Match’> <_sre.SRE_Match object; span=(0, 6), match=’bottle’> bottle bottle
<class ‘_sre.SRE_Match’> <_sre.SRE_Match object; span=(7, 10), match=’bag’> bag bag
<class ‘_sre.SRE_Match’> <_sre.SRE_Match object; span=(11, 14), match=’big’> big big
作業:(紅色標記未完成)
1.匹配郵箱地址,正確的
test@hot-mail.com
v-ip@magedu.com
web.manager@magedu.com.cn
super.user@google.com
a@w-a-com
[\w-]+@[\w-]+\.\w+ #沒有匹配w-a-com的那條
test@hot-mail.com
v-ip@magedu.com
manager@magedu.com
user@google.com
2.匹配html標記的內容
<\w\s\w+=\'(?<url>[^’]+)\’\s\w+=\'(?<target>[^’]+)\’>(?<name>\w+)
http://www.magedu.com/index.html’ target=’_blank’>馬哥教育
3.判斷密碼強弱
要求密碼必須由10-15位,指定字符串組成:
* 十進制
* 大寫字母
* 小寫字母
* 下劃線
* 要求四種類型的字符串都要出現才算合法的強密碼
*
思路:Alt text
4.單詞統計word count,對samplt.txt進行單詞統計,要求使用正則
代碼:Alt text

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/88239

(0)
Thunk_LeeThunk_Lee
上一篇 2017-11-05 23:38
下一篇 2017-11-06 19:37

相關推薦

  • 馬哥教育網絡班25期+第一周課程練習

    一、計算機的組成及功能     現代計算機的結構:馮諾依曼結構體系(儲存程序,順序執行),由20世紀30年代中期,美國科學家馮·諾依曼提出     馮.諾依曼結構處理器具有以下幾個特點:     1:必須有一個存儲器;2:必須有一個控制器;3:必須有一個運算器…

    Linux干貨 2016-11-28
  • sed使用方法

      sed編輯器被稱作流編輯器(stream editor)。流編輯器在處理數據之前基于預先提供的一組規則來編輯數據流。 一、命令格式   sed options '"地址""編輯命令"' file   常用選項:     -n:靜默模式,不顯示模式…

    Linux干貨 2015-12-28
  • tomcat基礎進階

                        tomcat基礎進階 前言 Tomcat Architecture Tomcat Installation Tomcat…

    Linux干貨 2016-04-22
  • Linux下的LVM管理命令

    一. 何為LVM?     Logical Volume Manager的縮寫,它可以把多個分區、硬盤甚至RAID組合成一個存儲設備來使用,并可以擴展或縮減空間。LVM有三層組成組成:底層的PV,中間的VG,上層的LV,如圖所示         &n…

    Linux干貨 2015-12-06
  • 第三周作業

      1、列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。 who | cut -d" " -f1 | sort -u who | cut -d" " -f1 | uniq 2、取出最后登錄到當前系統的用戶的相關信息。    who | tail -1 …

    Linux干貨 2016-11-19
  • 馬哥教育網絡班20期+第三周課程練習

    1. 列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。 [oracle@ocp ~]$ who root     pts/1        2016-06-26 …

    Linux干貨 2016-06-26

評論列表(1條)

  • 逆神陽
    逆神陽 2017-11-06 20:27

    朋友,你看的是多少期的內容?怎么會有這么多的知識呢?

欧美性久久久久