python之正則表達式(附帶兩個案例,隨時可用)

    正則表達式,相信不少人對它又愛又恨吧,愛的人,用起來如魚得水,不但會提升效率,成就感也會爆棚,看到別人爲了提取某些信息時,一堆split,還常常出錯,在別人在抓耳撓腮發愁怎麼定位時,你已經把工做交接了出去,捧着泡枸杞的保溫杯給別人指導時,別提多愜意了.css

反之別人此時的心情.python

    仍是不要太嘚瑟, 當心放學被打.咳咳,,,,跑題了(小猿有時候會本身腦補一下某些場景).接下來我們就開始正題吧.正則表達式

首先來講,正則表達式是很強大的, 能夠用在任何的語言中,能夠獲取到你想匹配的任何信息,強大的同時,必然它也是繁瑣的,相信你們在工做中大多數也是這樣的吧,想要獲取某段信息的中間的某些字段,我想第一反應仍是使用split吧,split來split去,最終split了一堆,可能也拿不到咱們想要的數據而且還不通用,經常在這裏報bug,之因此這樣說,我就是這樣的人,以前使用ECU-Test測試工具作自動化測試的案例,中間有一個步驟須要將文件存儲路徑改爲雲盤路徑,可是基於工具自己的限制,須要對存儲路徑作一下手動處理,因而就開始了split的過程, 具體就不描述了,bug頻出.微信

    最終實在無法,老老實實寫了一個正則表達式替代,解決問題.因此會正則表達式真的很重要.怎麼會?每天見她,天然就會了.沒事的小猿也會幫你的.app

接下來,先從簡單的作起.socket

首先是須要了解一些常見字符表明的含義,這個你們沒必要強行記憶,由於不用即使記住了也會很快就忘的.ide

普通字符工具

字符 描述(含義)
\cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須爲 A-Z 或 a-z 之一。不然,將 c 視爲一個原義的 'c' 字符。
\f 匹配一個換頁符。等價於 \x0c 和 \cL。
\n 匹配一個換行符。等價於 \x0a 和 \cJ。
\r 匹配一個回車符。等價於 \x0d 和 \cM。
\v 匹配一個垂直製表符。等價於 \x0b 和 \cK。
\t 匹配一個製表符。等價於 \x09 和 \cI。
\S 匹配任何非空白字符。等價於 \f\n\r\t\v
\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。注意 Unicode 正則表達式會匹配全角空格符。

特殊字符:(指的是自己就有含義的字符,若是單純想匹配須要轉義).測試

特別字符 描述
$ 匹配輸入字符串的結尾位置。若是設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符自己,請使用 $
( ) 標記一個子表達式的開始和結束位置。子表達式能夠獲取供之後使用。要匹配這些字符,請使用 ()
* 匹配前面的子表達式零次或屢次。要匹配 * 字符,請使用 *
+ 匹配前面的子表達式一次或屢次。要匹配 + 字符,請使用 +
. 匹配除換行符 \n 以外的任何單字符。要匹配 . ,請使用 .
[ 標記一箇中括號表達式的開始。要匹配 [,請使用 [
? 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?
\ 將下一個字符標記爲或特殊字符、或原義字符、或向後引用、或八進制轉義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\' 匹配 "\",而 '(' 則匹配 "("
^ 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符自己,請使用 \^
{ 標記限定符表達式的開始。要匹配 {,請使用 {
| 指明兩項之間的一個選擇。要匹配 |,請使用 |

限定匹配數量符: 和貪婪匹配以及非貪婪匹配相關.url

字符 描述
* 匹配前面的子表達式零次或屢次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}
+ 匹配前面的子表達式一次或屢次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}
? 匹配前面的子表達式零次或一次。例如,"do(es)?" 能夠匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價於 {0,1}
{n} n 是一個非負整數。匹配肯定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',可是能匹配 "food" 中的兩個 o
{n,} n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的全部 o。'o{1,}' 等價於 'o+'。'o{0,}' 則等價於 'o*'
{n,m} m 和 n 均爲非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價於 'o?'。請注意在逗號和兩個數之間不能有空格

接下來是中括號 即[]

使用方法是這個裏面加上要匹配的信息,好比數字,字母,下劃線等等,後面經常帶着的就是限定匹配數量符啦,能夠限制咱們匹配的信息的數量,

你們能夠從下面的在線測試工具中測試本身寫的正則

點我直達

或者點我

好了,拿到寫好的正則,接下來就是運用到代碼中了.

首先是re.match, search的用法

先說一下他們兩個的對比match的一個特色就是從左向右完整的去匹配,多出來的無論,少了就不行;
search是在給定字符串當中去搜索的符合正則表達式的內容。matchsearch的語法都同樣,都爲re.xxxx(正則表達式,字符串)
import re
# 首先是match,以一個分析日誌trace爲例# 這條trace的信息以下# Line 20: 26483 2020/01/06 14:07:21.000000 41106.6294 14 BAM2 ALL AQQ 1276 log info verbase 2 MQRC number received: +128546859637
# 須要作的是將後面的手機號提取出來進行下一步的操做def func(trace_informations): phone_nums = [] for trace_information in trace_informations: try: regex = re.compile( r"([\s\S].*?(?P<phone_num>[\d]{12}))" ) current_phone_num = regex.search( trace_information[-1]).group('phone_num') phone_nums.append(current_phone_num) print(current_phone_num) except: pass phone_num = len(list(set(phone_nums))) return phone_num, phone_nums

    上面使用的是[\s\S].*?來匹配前面全部的無關信息,後面是匹配數字,這樣就拿到了屬於這種格式的trace的電話信息.

再有就是使用正則取出咱們想要的信息字段進行路徑從新組合.

import datetimeimport reimport socketdef replace_image_file_path(test_result): """ Dealing with the unexpected image file path generated by ECU_TEST when upload file path like \\Public. the expected file path is \\WINFS but ECU generate it as c:\\users :param test_result: dictionary that including image file path {'img_folder': 'c:\\users\','trace_folder': 'c:\\users'} :return: expected image file full path. """ # old_trace_file_path = 'c:/users/qxz0cin/appdata/local/temp/test_for_upload_2019-11-01_102230_jx3waq/test_trace_for_upload/Images' old_img_file_full_path = test_result['img_folder'] img_file_tmp_path = old_img_file_full_path.split('local\\temp\\')[1] # img_file_tmp_path = 'test_for_upload_2019-11-01_102230_jx3waq/test_trace_for_upload/Images' p_disk_url = r'\\WINFS\EC-DATA\E2E_File_Server' p_disk_report_saving_root_path = "\\" + socket.gethostname() + "_AutoTestReports" if datetime.datetime.now().month < 10: time_pattern = str(datetime.datetime.now().year) + "-0" + \ str(datetime.datetime.now().month) else: time_pattern = str(datetime.datetime.now().year) + "-" + \ str(datetime.datetime.now().month) regex = re.compile( r"(?P<project_name>(?P<case_name>[\s\S]*?)_(%s)-[\d]{1,2}_[\d]+)?(_[a-z0-9A-Z_-]*)?(\\)?(?P<test_case_name>[\s\S]*)[\s\S]*?" % time_pattern) current_project_name = regex.search( img_file_tmp_path).group('project_name') current_testcase_name = regex.search( img_file_tmp_path).group('test_case_name') new_img_file_full_path = p_disk_url + p_disk_report_saving_root_path + \ "\\" + current_project_name + "\\" + current_testcase_name test_result['img_folder'] = new_img_file_full_path
def func(test_result): replace_image_file_path(test_result) return test_result
    其實上面的方案也不是最好的解決方案,可是至少目前這兩個案例已經成功執行半年之久,沒有再改動過,固然要是大牛們以爲還能夠改進還歡迎能在下方留言予以指正,小猿會越作越好的.高質量的文章少不了各位的支持.今天就到此位置啦.這兩個案例你們能夠拿去測試.有問題就提刀來砍我(渣渣輝臺詞,哈哈哈).


本文分享自微信公衆號 - IT民工技術之路(python_er)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索