主頁 > 後端開發 > 說說正則運算式

說說正則運算式

2021-09-03 06:30:07 後端開發

1 引言

網上說正則式的文章很多,剛開始有同事提議寫寫正則式,我實際上是有點拒絕的,畢竟看看別人的文章基本上就能滿足需求了,純粹做搬運工有點心有不甘,但要寫的有新意確實也很困難,

但回想起自己剛接觸正則運算式時的窘境,也看到csdn上還有一些沒什么油鹽的正則運算式文章居然還開收費,覺得還是有一些可說的,

2 正則運算式的使用場景

正則運算式,英文全稱是regular expression或者rational expression,從字面意思看regular表示常規的,合規的,正常的等含義;rational表示合理的,理性的等含義,

這個概念起源于數學家Stephen Cole Kleene1951年在《神經網路和有限自動機的事件表達》定義了一種新的數學描述語言regular events,該文章中引入了EvF, EF, E*F等運算式,這也算是正則運算式的雛形,

常規使用正則式的場景主要有編程語言、命令列、文本編輯器這三種,

2.1 編程語言

編程語言不用多說,為了實作某個功能,功能里面可能就要求支持正則匹配進行搜索和替換,

基本上大家現在還在使用的高級語言都支持正則運算式,部分是編程語言原生就支持,部分需要使用第三方的類別庫方式來支持,

例如:python,bash,c++,java,php,perl等,

2.2 命令列界面

這個和編程語言類似,主要是各種shell,和編程語言的差別無非是即寫即用,shell可以認為是一個字符流的執行物體,這個字符流中任意一個全集或者子集都可以應用到正則運算式,里面使用正則運算式最突出的是linux的三件套,grep、sed和awk,

2.3 各種編輯器

很多文本編輯器的搜索和替換,都支持正則運算式(很遺憾,office還不支持正則運算式),例如常用的notepad++,sublime text,vscode等等,

在處理一個文本檔案的時候,會點正則運算式經常會有事半功倍的效果,

舉個例子,很多web頁面對右鍵事件和選擇事件做了捕獲,這使得正常的拷貝動作,即使是文本拷貝,在對應網站上沒法實作,用開發者工具類似的功能能看到web的源代碼,并將對應段的html代碼拷貝出來,但html代碼中有大量的tag,會影響我們獲取純文本,使用下面的正則運算式可以匹配所有tag,替換成空就可以達到保留純文本的目的:

<[^>]*>

 

3 正則運算式的風格

現在大家使用的正則運算式已經不是Stephen Cole Kleene定義的最原始版本的regular events了,比較普遍的主要有兩種風格,POSIX和PCRE,

3.1 POSIX Extended 1003.2

和網路協議堆疊里面的ISO和TCP/IP對應,正則運算式也存在一個國際標準和一個事實標準,

POSIX Extended 1003.2是電氣和電子工程師協會(IEEE)制定的,相當于國際標準,但實際上各種編程語言對它的支持并不好,或者有些是部分支持,Bash默認的是POSIX風格的正則運算式,但部分命令,例如grep可以使用-E(POSIX Extended 1003.2),-G(BRE)和-P(PCRE)來指定不同風格的正則運算式,

3.2 PCRE

PCRE相當于事實標準,基本上絕大多數編程語言都支持PCRE,當然最早在編程語言中支持正則運算式的Perl更是因為PCRE在文本處理中一騎絕塵,很多后起的編程語言,都依賴Perl的相關設計來指定自己的文本處理規則,

Python編程語言和notepad++/sublime text這兩種編輯器是perl風格的正則運算式,有一些編程語言,例如PHP,2種風格都支持,

 

3.3 其他風格

由于POSIX Extended 1003.2沒有對多位元組字符的說明,PHP做POSIX標準(ereg)的基礎上,還支持了多位元組字符的POSIX標準(mb_ereg),

PCRE依賴修正符u來支持UTF-8格式的正則運算式,

 

3.4 POSIX Extended 1003.2和PCRE的差異

3.4.1 定界符

POSIX Extended 1003.2沒有定界符,PCRE有定界符,并且除了字母、數字和反斜線\以外的任何字符都可以做定界符,

為什么POSIX Extended 1003.2沒有定界符?

這要從PCRE為什么有定界符來說起,PCRE引入定界符主要是為了給修正符一個合適的位置,也就是說一對定界符包圍的字串之外的字符就是修正符,POSIX Extended 1003.2不支持修正符,所以也沒有必要支持定界符,

3.4.2 修正符

PCRE中支持11種修正符,方便正則運算式的使用更加靈活:

i(忽略大小寫),m(多行修正),s(.包含換行符),x(忽略空白字符,轉義的空白除外),e(支持逆向參考),A(強制從開頭開始匹配),D($匹配換行符,m設定的話該引數無效),S(加速匹配),U(?使用貪婪模式),X(待擴展),u(默認UTF-8)

3.4.3 POSIX Extended 1003.2的型別匹配

[:upper:]:匹配所有的大寫字母

[:lower:]:匹配所有的小寫字母

[:alpha:]:匹配所有的字母

[:alnum:]:匹配所有的字母和數字

[:digit:]:匹配所有的數字

[:xdigit:]:匹配所有的十六進制字符,等價于[0-9A-Fa-f]

[:punct:]:匹配所有的標點符號,等價于[.,"'?!;:]

[:blank:]:匹配空格和TAB,等價于[ \t]

[:space:]:匹配所有的空白字符,等價于[ \t\n\r\f\v]

[:cntrl:]:匹配所有ASCII 0到31之間的控制符,

[:graph:]:匹配所有的可列印字符,等價于:[^ \t\n\r\f\v]

[:print:]:匹配所有的可列印字符和空格,等價于:[^\t\n\r\f\v]

[.c.]:未定義

[=c=]:未定義

[:<:]:匹配單詞的開始

[:>:]:匹配單詞的結尾

3.4.4 PCRE的型別匹配

\a alarm,即 BEL字符(’0)

\cx "control-x",其中 x 是任意字符

\e escape(’0B)

\f 換頁符 formfeed(’0C)

\n 換行符 newline(’0A)

\r 回車符 carriage return(’0D)

\t 制表符 tab(’0)

\xhh 十六進制代碼為 hh 的字符

\ddd 八進制代碼為 ddd的字符,或 backreference

\d 任一十進制數字

\D 任一非十進制數的字符

\s 任一空白字符

\S 任一非空白字符

\w 任一數字、字母或下劃線的字符

\W 任一非數字、字母或下劃線的字符

\b 字分界線

\B 非字分界線

\A 目標的開頭(獨立于多行模式)

\Z 目標的結尾或位于結尾的換行符前(獨立于多行模式)

\z 目標的結尾(獨立于多行模式)

\G 目標中的第一個匹配位置

4 一個復雜模式匹配的替換程序

常規的查找相對都比較簡單,只要歸納總結一下字符流的規律就可以形成匹配的正則運算式,常規的提取和替換也支持對第幾個匹配項的提取,這在模式匹配中也非常常用,

 

如果通過某種通配模式匹配下來的字符經過一定復雜處理之后再進行替換怎么處理?一些編程語言還提供了回呼的方式進行替換,

例如python手冊re — Regular expression operations — Python 3.9.7 documentation里面的這個re模塊的例子:

>>> import re >>> def dashrepl(matchobj): ...     if matchobj.group(0) == '-'return ' ' ...     elsereturn '-' ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub('-{1,}', dashrepl, 'pro----gram-files') 'pro-gram files'

其中dashrepl定義了一個回呼函式,對于使用'-{1,2}'匹配一個或者兩個-的情況下,分別針對單個-或者兩個-的情況替換為慷訓者-;而在使用'-{1,}'匹配一個或者多個-的情況下,分別針對單個-或者多個-的情況替換為慷訓者-,

 

5 參考資料

5.1  posix和perl標準的正則運算式區別_lcy_ltpsr的專欄-CSDN博客_posix和perl標準的正則運算式區別

5.2 Representation of Events in Nerve Nets and Finite Automata | RAND

5.3 re — Regular expression operations — Python 3.9.7 documentation

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296988.html

標籤:Python

上一篇:PyTorch自動求導

下一篇:面試官:Minor GC、Major GC、Full GC 區別?我竟然答不上來。。

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more