1. 程式人生 > >第23天 常用模組四

第23天 常用模組四

介紹的模組

re模組
subprocess模組

人生三問

什麼re模組
    主要是與正則表示式相關操作的一些方法

什麼是正則表示式
    就是一系列特殊意義字元的組成的式子。

為什麼要用正則表示式呢?
    在日常生活中我們獲得的資料大部分都是一大串的字串,但是通常情況下我們並不是需要整個字串,我們需要的是一些有規律的資料,怎麼去把他們提取出來就變成了一個難題,
   這個時候正則表示式就出現了,我們可以通過寫的一些正則表示式對字串進行分析提取,最後獲得我們需要的內容。

正則表示式:

'''
正則表示式
位置匹配
    \A 開頭
    \Z 結尾
    
^ 開頭 $ 結尾 範圍匹配 \d 數字 (\D相反是非數字) \w 數字字母下劃線 (\W相反) \s 空字元(\t\n\f\b) (\s相反) [...] 手動指定範圍,ascii碼錶返回 [^...] 指定範圍以外的內容 重複匹配 * 0次或者多次 + 一次或者多次 ? 0次或者一次 非貪婪模式 {n} 精確匹配前面n個表示式 {n, m} 匹配n到m次由前面的正則表示式定義的片段,貪婪模式 分組 ()括號內的表示式是一個分組 '''

示例一:單個字元的匹配

>>> import re
>>> re.findall('\w', 'hello egon 123')
['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
>>> re.findall('\W', 'hello egon 123')
[' ', ' ']
>>> re.findall('\d', 'hello egon 123')
['1', '2', '3']
>>> re.findall('
\D', 'hello egon 123') ['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' '] >>> re.findall('\s', 'hello egon 123') [' ', ' '] >>> re.findall('\S', 'hello egon 123') ['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3'] >>> re.findall('\Ahe', 'hello egon 123') ['he'] >>> re.findall('^he', 'hello egon 123') ['he'] >>> re.findall('3$', 'hello egon 123') ['3'] >>> re.findall('3\Z', 'hello egon 123') ['3']

示例二:重複匹配

# 重複匹配之.
>>> re.findall('a.b', 'a1b')  # 任意字元
['a1b']
>>> re.findall('a.b', 'a1b a*b a b aaab')
['a1b', 'a*b', 'a b', 'aab']
>>> re.findall('a.b', 'a\nb')  # 不能匹配換行符
[]
>>> re.findall('a.b', 'a\nb', re.S)  # 只要加上這個引數就可以匹配換行符
['a\nb']
>>> re.findall('a.b', 'a\nb', re.DOTALL)
['a\nb']
# 重複匹配之 * 0次或者多次
>>> re.findall('ab*', 'bbbbbb') # 沒有匹配到前面的a
[]
>>> re.findall('ab*', 'a')  # 匹配了b零次
['a']
>>> re.findall('ab*', 'abbbb')  # 匹配了b多次
['abbbb']
# 重複匹配之? 0次或者一次
>>> re.findall('ab?', 'a')  # 匹配了b零次
['a']
>>> re.findall('ab?', 'abbbb')  # 匹配了b1次
['ab']
# 重複匹配之 + 1次或者多次
>>> re.findall('ab+', 'a')  # 沒有匹配到b
[]
>>> re.findall('ab+', 'ab')  # 匹配了b1次
['ab']
>>> re.findall('ab+', 'abbbbb') # 匹配了b多次
['abbbbb']

示例三:{ }, [ ]的使用

正則表示式之{}
{2} 匹配前面模式兩次
{2,4}匹配前面模式兩到四次,注意中間不能加空格
>>> re.findall('ab{2}', 'abbb')  # 匹配了b兩次
['abb']
>>> re.findall('ab{2,4}','abbb') # 匹配字元2次到四次
['abbb']
>>> re.findall('ab{1,}', 'abbb')  # 匹配1次或者多次,預設貪婪匹配,所以匹配了三次
['abbb']
>>> re.findall('ab{0,}', 'abbb') # 匹配0次或者多次,預設貪婪匹配,所以匹配了三次
['abbb']
>>>

正則表示式之[]
[abcd] 匹配[]裡面的任何字元
>>> re.findall('a[1*-]b', 'a1b a*b a-b')  # a和b是固定的,但是中間的值可以是1 * -
['a1b', 'a*b', 'a-b']
>>> re.findall('a[^1*-]b', 'a1b a*b a-b a=b') # ^代表a和b之間不能是[]內的任意字元
['a=b']
>>> re.findall('a[0-9]b', 'a1b a*b a-b a=b')   # ab之間可以是0-9之間的數字
['a1b']
>>> re.findall('a[a-z]b', 'a1b a*b a-b asb')   # ab之間是a-z之間的數字
['asb']
>>> re.findall('a[A-Z]b', 'aSb a*b a-b asb')    # ab之間是A-Z之間的數字
['aSb']
>>> re.findall('a[A-Za-z]b', 'aSb a*b a-b asb')  # ab之間是A-Z,a-z之間的數字
['aSb', 'asb']

匹配網址
import re

print(re.findall('href=".*?"', '<a href="http://www.baidu.com">點選</a>'))
# 結果:['href="http://www.baidu.com"']
print(re.findall('href="(http.*?)"', '<a href="http://www.baidu.com">點選</a>'))
# 結果 ['http://www.baidu.com']

示例四: 分組

#():分組
print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
print(re.findall('(?:ab)+123','ababab123')) #findall的結果不是匹配的全部內容,而是組內的內容,?:可以讓結果為匹配的全部內容

示例五:【\】的使用

# 因為python在使用正則表示式的時候是要交給底層的c去執行的
# 因此python直譯器首先要保證讓自己去識別斜槓的時候是正確的,這個時候需要兩個斜槓
# 當時當傳到底層的c去執行的時候,需要把讓c也知道這個是普通的字元,因此還需要兩個斜槓
text = 'a\c'
# 方法一:四個斜槓
print(re.findall('a\\\\c', text))
# 方法二: r + 兩個斜槓
print(re.findall(r'a\\c', text))
# 結果:
# ['a\\c']
# ['a\\c']

re模組的方法

re模組的方法
    findall  返回所有滿足匹配條件的值放在一個列表中
    search   在整個字串中尋找一個匹配的值
    match  從字串的開頭尋找一個匹配的值
    split  按照一個模式進行分割
    sub   替換字串
   complie  編譯

方法一: 匹配

>>> import re
>>> re.findall('e', 'alex make love') # 在字串中查找出所有的e放在一個列表中
['e', 'e', 'e']
>>> re.search('e', 'alex make love') # 在字串中查找出一個e返回一個物件,可以通過group去獲得相應的值
<_sre.SRE_Match object; span=(2, 3), match='e'>
>>> re.search('e', 'alex make love').group(0)
'e'
>>> re.match('e', 'alex make love') # 在字串的開頭查詢e發現沒有,所以沒有返回值,方法match可以被search + ^方法所取代
>>>

方法二:compile

>>> obj = re.compile('\d{2}')  # 直接把字串編譯成物件之後可以通過方法去直接呼叫
>>> obj.search('abc123eeee').group()  # 物件直接呼叫search去查詢對應的值
'12'
>>> obj.findall('abc123eeee')  #對之前編譯的物件進行了重用
['12']
>>>

方法三: sub

# 替換字串,第一個給匹配模組,第二個為替換物件,第三個為字串,第四個是替換幾個
>>> re.sub('a', 'A', 'alex make love') 'Alex mAke love' >>> re.sub('a', 'A', 'alex make love', 1) 'Alex make love' >>> re.sub('a', 'A', 'alex make love', 2) 'Alex mAke love' >>>

應用一:將字串的alex make love的第一個字串和第三個字串進行替換====》love make alex

# alex make love ===>love make alex
text = 'alex make love'
# 首先用正則表示式去表示我們的字串,表示成五組,[('alex', ' ', 'make', ' ', 'love', '')]
pattern = '^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$'
# print(re.findall(pattern, text))
print(re.sub(pattern, r'\5\2\3\4\1', text))

應用二:將字元"java|C++|js|C|python"替換成python|C++|js|C|java

# 將字串java與python進行替換
text = "java|C++|js|C|python"   # 這是一段字串
pattern = '(.+?)(\|.+\|)(.+)'  # 首先通過正則表示式去描述我們的字串,並且分組
# print(re.findall(pattern, text))
print(re.sub(pattern, r'\3\2\1', text))  # 根據分組去獲得我們的值

方法四:split

print(re.split("\|_*\|","python|____|js|____|java"))

模組二:subprocess

subprocess
    這是一個可以與其他程序進行資料互動的模組。
os.system
  也可以和其他的程序進行交換,但是不能進行資料互動,我們只能得到一個狀態碼。
兩個輸出,一個輸入
  stdout 標準輸出
  stdin  標準輸入
  stderr 標準錯誤輸出

方法:Popen

標準輸出

import subprocess

cmd = 'dir H:\python_study\day23 | findstr "py"'
# 建立了一個子程序, 把命令,標準輸出
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
# 得到的是系統的編碼方式,是gbk的編碼方式
print(sub.stdout.read().decode('gbk'))

標準錯誤輸出

import subprocess

cmd = 'd H:\python_study\day23 | findstr "py"'
# 建立了一個子程序, 把命令,標準輸出
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.PIPE)
# 得到的是系統的編碼方式,是gbk的編碼方式
# print(sub.stdout.read().decode('gbk'))
# 這個是當錯誤發生的時候會給我們返回一個標準錯誤輸出
print(sub.stderr.read().decode('gbk'))

標準輸入:

cmd = 'dir H:\python_study\day23'
find = 'findstr "py"'

sub1 = subprocess.Popen(cmd,
                        stdout=subprocess.PIPE,
                        shell=True,)
# 把sub1的標準輸出輸入到sub2的輸入中
sub2 = subprocess.Popen(find,
                        stdout=subprocess.PIPE,
                        stdin=sub1.stdout)

print(sub2.stdout.read().decode('gbk'))