1. 程式人生 > 實用技巧 >Python學習——正則表示式

Python學習——正則表示式

match方法:

match嘗試從字串的起始位置開始匹配

  • 如果起始位置沒有匹配成功, 返回None;

  • 如果起始位置匹配成功, 返回一個物件, 通過group方法獲取匹配的內容;

import re
# re:regular express 正則表示式
aObj = re.match(r'we', 'wetoshello')
print(aObj)
print(aObj.group())

# \d 單個數字
# \D \d的取反 , 除了數字之外
bObj = re.match(r'\d', '1westos')
if bObj:
    print(bObj.group())

bObj 
= re.match(r'\D', '_westos') if bObj: print(bObj.group())

findall方法:

findall會掃描整個字串, 獲取匹配的所有內容;

import re
res = re.findall(r'\d\d', '閱讀數為2 點贊數為10')
print(res)

search方法:

search會掃描整個字串, 只返回第一個匹配成功的內容的SRE物件;

resObj = re.search(r'\d', '閱讀數為8 點贊數為10')

if resObj:
    print(resObj.group())

二、正則表示式的特殊字元類

字元類:

[ ]匹配括號內多個字元中的任意一個字元

[^ ]表示匹配除了括號內的任意一個字元

  • [a-z]:匹配任意一個小寫字母

  • [A-Z]:匹配任意一個大寫字母

  • [a-zA-Z0-9]:匹配任意一個小寫或大寫字母或數字

  • [^0-9]:匹配除了數字的任意一個字元

特殊字元類:

  • .: 匹配除了\n之外的任意字元; [.\n]

  • \d: digit–(數字), 匹配一個數字字元, 等價於[0-9]

  • \D: 匹配一個非數字字元, 等價於[^0-9]

  • \s: space(廣義的空格: 空格, \t, \n, \r), 匹配單個任何的空白字元;

  • \S: 匹配除了單個任何的空白字元;

  • \w: 字母數字或者下劃線, [a-zA-Z0-9_]

  • \W: 除了字母數字或者下劃線, [^a-zA-Z0-9_]

^: 在[]前面表示以什麼開頭,在[]裡面表示除括號內字元之外的任意一個字元^: 以什麼開頭
$: 以什麼結尾
# 匹配數字
# pattern = r'\d'
pattern = r'[0-9]'
string = "hello_1$%"
print(re.findall(pattern, string))


# 匹配字母數字或者下劃線;
# pattern = r'\w'
pattern = r'[a-zA-Z0-9_]'
string = "hello_1$%"
print(re.findall(pattern, string))

# 匹配除了字母數字或者下劃線;
# pattern = r'\W'
pattern = r'[^a-zA-Z0-9_]'
string = "hello_1$%"
print(re.findall(pattern, string))

# .: 匹配除了\n之外的任意字元; [.\n]
print(re.findall(r'.', 'hello westos\n\t%$'))

指定字元出現的次數

匹配字元出現次數:

  *: 代表前一個字元出現0次或者無限次; \d*, .*

  +: 代表前一個字元出現一次或者無限次; \d+

  ?: 代表前一個字元出現1次或者0次; 假設某些字元可省略, 也可以不省略的時候使用,即去貪婪

第二種方式

  {m}: 前一個字元出現m次;

  {m,}: 前一個字元至少出現m次; * == {0,}; + ==={1,}

  {m,n}: 前一個字元出現m次到n次; ? === {0,1}

# *: 代表前一個字元出現0次或者無限次;    \d *,.*
print(re.findall(r'\d*', '234'))
print(re.findall(r'.*', 'hello223%'))
print(re.findall(r'd*', 'ddhello223%'))


#     +: 代表前一個字元出現一次或者無限次;     d+
print(re.findall(r'd+', ''))
print(re.findall(r'd+', 'dddderrttt'))
print(re.findall(r'\d+', '閱讀數: 8976 點贊數:900'))

#  ?: 代表前一個字元出現1次或者0次;   假設某些字元可省略, 也可以不省略的時候使用
# 2019-10
print(re.findall(r'\d+-?\d+', '2019-10'))
print(re.findall(r'\d+-?\d+', '201910'))
print(re.findall(r'\d{4}-?\d{1,}', '2019-1'))
print(re.findall(r'\d{4}-?\d{1,2}', '2019-10'))
print(re.findall(r'\d+-?\d+', '201910'))

三、北美號碼的合法性

問題描述: 北美電話的常用格式:(eg: 2703877865)

前3位: 第一位是區號以2~9開頭 , 第2位是0~8, 第三位數字可任意; 中間三位數字:第一位是交換機號, 以2~9開頭, 後面兩位任意 最後四位數字: 數字不做限制;

# 傳統正則 pattern = r'[2-9][0-8]\d[2-9]\d\d\d\d\d\d'

# 可以利用重複符號的方式 pattern = r'[2-9][0-8]\d[2-9]\d{6}'

def is_valid(pattern,tel):
    telObj=re.search(pattern,tel)
    if telObj:
        print('%s合法' %(tel))
    else:
        print('%s不合法' %(tel))

if __name__ == '__main__':
    pattern = r'[2-9][0-8]\d[2-9]\d{6}'
    is_valid(pattern,'2777777777')
    is_valid(pattern,'1777777777')

四、分組匹配

表示分組

  • | : 匹配| 左右任意一個表示式即可;

  • (ab): 將括號中的字元作為一個分組

  • \num: 引用分組第num個匹配到的字串

  • (?P): 分組起別名

  • (?P=name) : 引用分組的別名

print(re.findall(r'westos|hello', "hellowestos"))
# 進行分組的時候, findall方法只返回分組裡面的內容;
print(re.findall(r'(http|https)(.+)', 'http_hello'))

# search
sreObj = re.search(r'(http|https)(.+)', 'http_hello')
if sreObj:
    # group方法會返回匹配的所有內容;
    print(sreObj.group())
    # groups方法返回分組裡面的內容;
    print(sreObj.groups())

# 需求: 獲取標籤裡面的文字, 並判斷標籤是否成對出現?
htmlStr = "<html><p>welcome to westos!</p></html>"
pattern = r'<(\w+)><(\w+)>(.+)</\2></\1>'
print(re.findall(pattern, htmlStr))
print(re.findall(pattern, htmlStr)[0][2])

# 需求: 分組起別名?
htmlStr = "<html><p>welcome to westos!</p></html>"
pattern = r'<(?P<FirstTag>\w+)><(?P<SecondTag>\w+)>(?P<Text>.+)' \
          r'</(?P=SecondTag)></(?P=FirstTag)>'
print(re.findall(pattern, htmlStr))
sreObj = re.search(pattern, htmlStr)
if sreObj:
    print(sreObj.group())
    print(sreObj.groups())
    print(sreObj.groupdict())
    print(sreObj.groupdict()['Text'])

五、練習之URL合法性驗證

問題描述: 檢查某段給定的文字是否是一個符合需要的URL;

思路:

1). 檢查URL是否以web瀏覽器普遍採用的通訊協議方案開頭: http, https, ftp file

2). 協議後面緊跟 :// 3). 協議後面字元任意;

def isUrl(url):
    pattern = re.compile(r'^(http|https|ftp|file)://.+$')
    resObj = re.search(pattern, url)
    if resObj:
        return  True
    return  False


if __name__ == '__main__':
    print(isUrl('file:///tmp'))
    print(isUrl('http://www.baidu.com'))
    print(isUrl('https://www.baidu.com'))
    print(isUrl('ftp://www.baidu.com'))

六、匹配漢字

字串是否包含中文 []表示匹配方括號的中任意字元,\u4e00是Unicode中漢字的開始,\u9fa5則是Unicode中漢字的結束

user = '南京郵電大學123函式'
pattern = r'[\w\-\u4e00-\u9fa5]+'
print(re.findall(pattern, user))