成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

正則表達式-從模糊到清晰

開發 前端
正則是一些用來匹配和處理文本的字符串(或者叫工具),往往用于查找特定的信息(搜索),或者查找并編輯特定的信息(替換)。它是一種內置在其他語言里的一種“迷你”語言,比如內置在Javscript、Java等語言中。

[[212469]]

1. 什么是正則

簡單點,正則是一些用來匹配和處理文本的字符串(或者叫工具),往往用于查找特定的信息(搜索),或者查找并編輯特定的信息(替換)。它是一種內置在其他語言里的一種“迷你”語言,比如內置在Javscript、Java等語言中。

2. 要認可的事實

正則答案不唯一。幾乎所有的問題,往往都會有不止一種解決方案。有的比較簡單,有的比較快速,有點兼容性更好,有的功能更全。我們需要依據自己的需求,確認一種最適合自己的方案。

3. 正則引擎概述

正則引擎可以分為2類。一種稱之為NFA(非確定型有窮自動機),另一種稱之為DFA(確定型又窮自動機)。嗯,概念不好理解,我們舉個栗子:

正則:to(Jack|Rose|Jerry)

匹配文本:xxx···toJerry

1)NFA(表達式主導)匹配過程

正則表達式從正則的***個 t 開始,每次由正則引擎查看表達式的一部分,同時檢查當前文本是否匹配表達式的當前部分。如果是,則繼續表達式的下一部分,如果繼續,直到表達式的所有部分都能匹配到。此時發現當檢查到當前文本中的字符 t 時,所以正則表達式的***項匹配成功,接著會檢查緊跟其后的字符是否能由 o 來匹配,然后發現可以,則接著檢查后面的元素,此時后面的元素是 (Jack|Rose|Jerry) ,引擎會嘗試著3種可能進行分別測試,直到匹配成功。

2)DFA(文本主導)匹配過程

引擎在掃碼當前文本的時候,會記錄當前有效的所有匹配可能。當引擎移動到文本的 t 時,它會在當前處理的匹配可能中添加一個潛在的可能:

接下來掃描的每個字符,都會更新當前的可能匹配序列。例如掃碼到匹配文本的 J 時,有效的可能匹配變成了2個,Rose被淘汰出局。

掃描到匹配文本的 e 時,Jack也被淘汰出局,此時就只剩一個可能的匹配了。當完成后續的rry的匹配時,整個匹配完成。

3)兩句話點評NFA與DFA

  1、DFA匹配速度快但特性少(比如不支持捕獲組、反向引用),NFA匹配稍慢但能力強大;

  2、DFA就好比搭載電動發動機的汽車,加速度很快,但續航短,不能出遠門,而NFA可以認為是汽油發動機的汽車,加速度沒那么快,但是適應性廣,哪里都能去,但由于適應性廣,所以調教很重要。

4)需要注意的

Java、Javascript、PHP、Python這些都是NFA引擎。

4. 過基礎(老手請跳過)

5. 要點講解

1)貪婪與懶惰

貪婪模式:

盡可能匹配更多的字符。舉個栗子:

正則:<p>.*</p>

結果:

從匹配過程我們也可以發現對于 .* 這個表達式會嘗試盡可能多的匹配字符,直到匹配到盡頭,才嘗試匹配正則結尾的 </p> 。

懶惰模式:

與貪婪模式相反,盡可能匹配更少的字符。舉個栗子:

正則:<p>.*?</p>

結果:

從匹配過程我們也可以發現,會優先匹配正則結尾的 </p> ,在沒有滿足此結尾的情況下,才盡可能的去少匹配 .*? 這個表達式。

2)子表達式與反向引用

子表達式:

考慮這種場景,有些短語雖然由多個單詞構成,但其實是一個整體,需要把它當做一個獨立元素來使用,這種時候就需要使用子表達式。子表達式必須用()圓括號括起來。用途就是,可以精確的設定需要重復匹配的文本及重復次數。

反向引用:

它允許我們在正則中引用之前子表達式匹配到的結果。這有什么用?還是舉個栗子:

需求:匹配Html代碼片段中的h1~h6標簽

正則:<h[1-6]>.*?</h[1-6]>(沒有使用反向引用)

結果:

正則:<h([1-6])>.*?</h1>(使用了反向引用)

結果:

3)回溯

NFA引擎匹配能力強大,但是調教不好,有可能引發性能問題,它有另一個叫法,叫做回溯失控。那么問題來了,什么是回溯?

舉個栗子:

我們醒來的時候,突然發現被困在山洞里,這時候需要尋找出路,然而前方是一個岔路口。這個時候也并沒有任何依據可以告訴我們哪一條是出路,只有挨個嘗試,于是我們可以在岔路口做個標記,以便萬一選擇的這條路走不通,可以原路返回,直到遇見做了標記的岔路口,以便繼續嘗試另一條路是不是出路。我們可以把每次嘗試失敗然后往回走,找到之前做標記的地方的這個過程,稱之為回溯。

很多情況下,依據你寫的正則表達式,正則引擎或多或少都需要進行這種2個或者多個選項的選擇。

4)斷言(環視)

先不做專業術語解釋,先來看這么一個應用場景

需求:匹配網頁里所有PC商品詳情頁地址所包含的sku信息

PC商品詳情頁地址格式://item.jd.com/xxxxxx.html

方法一:先正則匹配,再截斷后面固定的.html

正則:/d+\.html/g

方法二:先正則匹配,再截斷前后固定的字符

正則:/item\.jd\.com/d+\.html/g

方法三:使用正向斷言和反向斷言,保證準確性,同時只返回sku數字

正則:/(?<=item\.jd\.com/)d+(?=\.html)/g

斷言分類:正向肯定斷言、正向否定斷言、反向肯定斷言、反向否定斷言

需要注意的:Javascript不支持反向斷言,Java也是有限制的支持反向斷言

總而言之,言而總之,當我們匹配目標關鍵字的時候,同時期望對目標關鍵字的前后進行限制,并且又不期望這些限制會出現在匹配結果中。這時候,就可以使用斷言。

6. 正則優化

1)怎樣才算是一個好正則

準確性:只匹配期望的文本,排除掉不期望的文本

需求:匹配jshop手機活動頁url的域名部分

jshop手機活動頁URL格式://xxxx.jd.xxx/m/act/xxxxxx.html

正則:///(.*)(?=/m)/g

正則:///(1*)/g

點評:如果不需要匹配/,那就應該在正則表達式中作出這樣的規定

匹配效率:很快返回匹配結果,如果不能匹配,盡可能短的時間報告匹配失敗

 

前面有提到過,NFA引擎功能強大,但是寫不好很容易引發效率問題。其中太多的多選分支很容易成為效率殺手,因為任何多選分支只要匹配失敗,都會導致回溯。所以提高正則匹配效率的方法之一就是減少多選分支。

舉個栗子:

需求:匹配用戶輸入的一個字符串是否是一個4位IP里的一位,直白的說就是匹配0~255

分析:可能有1位,也可能有2位,也可能有3位。3位的時候需要分開判斷,當***位是0或者1的時候,后面兩位可以是任意數字。當***位是2的時候,第二位只能是0-5。并且當第二位是0-4的時候,第三位可以是任意數字,但第二位是5的時候,第三位只能是0-5。

翻譯過來正則:/d|dd|[01]dd|2[0-4]d|25[0-5]/

合并同類項后:/[01]?dd?|2[0-4]d|25[0-5]/

點評:可以通過合并同類項來減少多選分支。同時***個多選分支使用的是 dd? 而不是 d?d ,這樣如果根本不存在數字,NFA引擎會更快地報告失敗

易讀性

……

2)使用工具

分析正則表達式

比如這個網站 https://jex.im/regulex

可以實現對復雜整個表達式的一個

測試正則表達式性能

比如這個貓頭鷹工具 RegexBuddy

可以用來測試正則表達式的匹配過程以及性能,包括各種語言下的正則特性支持情況。

3)優化手段

優化方針:減少回溯

1、減少或者合并多選分支

2、避免量詞的嵌套

3、占有優先量詞。可以減少回溯,遺憾的是js不支持,但java支持。

舉個栗子:考慮到 /a+b/ 和 /a++b/ 兩個正則,測試的字符串 aaaa

/a+b/ 的匹配過程

/a++b/ 的匹配過程

4、使用正確的邊界匹配器(^、$、b、B等),限定搜索字符串位置

5、盡量不使用通配符".";字符使用具體的元字符、字符類(d、w、s等)(推薦)

6、使用正確的量詞(+、*、?、{n,m}),如果能夠限定長度,匹配***

7、使用非捕獲型括號。如果不需要引用括號內的文本,請使用非捕獲型括號(?:……),好處就是節省捕獲時間,同時減少回溯使用的狀態數量。 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2018-09-27 15:25:08

正則表達式前端

2020-09-04 09:16:04

Python正則表達式虛擬機

2024-09-14 09:18:14

Python正則表達式

2016-11-10 16:21:22

Java 正則表達式

2009-09-16 17:15:57

正則表達式引擎

2022-01-04 11:35:03

Linux Shel正則表達式Linux

2023-09-13 08:12:45

2010-03-25 18:25:36

Python正則表達式

2017-05-12 10:47:45

Linux正則表達式程序基礎

2022-03-28 06:19:14

正則表達式開發

2021-01-27 11:34:19

Python正則表達式字符串

2009-02-18 09:48:20

正則表達式Java教程

2019-07-17 15:45:47

正則表達式字符串前端

2009-09-16 18:19:34

正則表達式組

2011-06-02 12:34:16

正則表達式

2012-04-28 15:22:46

PHP

2011-06-16 16:05:23

正則表達式

2010-07-13 17:03:53

Perl正則表達式

2010-07-14 09:01:18

Perl正則表達式

2010-07-19 10:40:16

Perl正則表達式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 男女羞羞视频在线看 | 亚洲欧美日本国产 | 日韩在线免费电影 | 97久久久久久久久 | 精品视频在线免费观看 | 国产精品久久午夜夜伦鲁鲁 | 99精品网| 久久国产精品一区二区 | 美女视频网站久久 | 中文亚洲视频 | 日本精品裸体写真集在线观看 | 男人天堂色 | 久久91av| 天天夜天天操 | 国产日韩精品视频 | 精品在线一区二区 | 中文在线一区 | 国产精品一卡二卡三卡 | 欧美黑人一级爽快片淫片高清 | 久久成人免费观看 | 亚洲精品不卡 | 91小视频在线 | 久久成人免费视频 | 国产色| 嫩草一区二区三区 | 在线91| 天天干天天想 | 在线观看成人精品 | 亚洲一区二区三区视频在线 | 一区免费| 久久精品一 | 韩国主播午夜大尺度福利 | 黄视频免费在线 | 成人午夜激情 | 久久99深爱久久99精品 | 国产一区二区电影 | 91精品久久久久久久久久小网站 | 91精品国产一区二区三区 | 国产一区二区不卡 | 中文字幕一区二区三区不卡 | 97色免费视频 |