正規表示式 貪婪與非貪婪

2022-08-21 20:12:10 字數 2100 閱讀 3302

在一段時間內,一直不知道.*.*?之間的區別,一直單純的覺得兩者之間並沒有什麼區別,都是匹配任意字元,知道今天才知道其中的區別

首先從乙個簡單的問題的問題開始思考:

有這樣乙個字串aaabaaab,和這樣的乙個正則.*b,那麼.*匹配的會是aaab還是aaabaaab呢?

由此問題引發出來的就是貪婪與非貪婪模式的區別,簡單的說,它們之間的區別就在於貪婪模式匹配的是aaabaaab而非貪婪模式下匹配的是aaab

當然,僅僅是.*b並不足以決定到底是按照貪婪還是非貪婪模式匹配,所以使用?來判斷是否是貪婪模式

所以.*?b就決定其使用非貪婪模式進行匹配

那麼,具體來說,貪婪和非貪婪模式是怎麼進行匹配的呢?

待匹配的字串:"abc"

正則:".*"

貪婪模式

其中進行了一次回溯

非貪婪模式

其中進行了三次回溯

ctf那麼貪婪模式與非貪婪模式有什麼用途呢?

在鳥哥的部落格中,可以看到這樣的**

$reg = "/"; //長度大於100014

$ret = preg_replace($reg, "", $str); //返回null

由於使用了非貪婪模式進行匹配,所以會導致進行不斷的回溯,最後由於回溯次數超過php的回溯限制,導致返回false,藉此可以繞過一些ctf中的waf

php的回溯限制可以在pcre擴充套件中看到,預設為100000

lctf2017

在lctf2017中,可以看到這樣的部分

preg_match('/^(xdsec)((?:###|\w)+)$/i', $code, $matches);

if (count($matches) === 3 && $admin === $matches[0])

正則匹配字串,如果匹配成功則將匹配結果填充進matches陣列,並進行判斷是否與$admin變數相同,但是進行匹配的話matches[0]的值將會是字串本身,無法進行到下一步

所以這裡輸入乙個非常長的字串,讓其匹配,因為在進行正則匹配的時候一定會消耗計算機資源進行乙個字元的匹配(預設是貪婪模式),所以會導致php超時,使得後面的語句不會執行

code-breaking puzzles

先膜p師傅orz

**如下

<?php

function is_php($data)

if(empty($_files))

$user_dir = 'data/' . md5($_server['remote_addr']);

$data = file_get_contents($_files['file']['tmp_name']);

if (is_php($data)) else

$reg = /(.+?)+/is;

$str = str_pad("laruence", 10000, "a"); //長度為1萬

$ret = preg_repalce($reg, "", $str);

這裡的主要目的也是為了要繞過正則,但這裡和上面不同,上面利用的是貪婪匹配導致資源耗盡

而這題使用的正是回溯

因為.的存在,且預設是貪婪模式進行匹配,所以.會一直匹配到字串結尾,然後進行回溯,如果沒有找到,會再次回溯,所以只要字串的長度超過回溯次數,自然就能繞過正則了

初次在遇到lctf那題的時候,沒有仔細去思考背後的東西……只知道正則匹配是很消耗資源的,卻不知道為何會消耗資源。之前也曾遇到過貪婪和非貪婪的名詞,沒有去了解。也層遇到過.*?的寫法,沒有去了解,果然,就像p師傅說的那樣,不求甚解是進步的最大阻礙,下次再遇到問題時,需要更進一步思考,弄明白原理

做題記錄/

正規表示式 貪婪與非貪婪匹配

貪婪匹配與非貪婪匹配 貪婪匹配 預設情況下,正規表示式使用最長匹配原則 也叫貪婪匹配原則 例如 要將 zoom 中匹配 zo?的部 分替換成 r 替換的的結果是 rom 如果要將 zoom 中匹配 zo 的部分替換成 r 替換後的結果是 rm 非貪婪匹配 當字元?緊隨其他限定符 之後時,匹配模式變成...

正規表示式貪婪與非貪婪模式

之前做程式的時候看到過正規表示式的貪婪與非貪婪模式,今天用的時候就想不起來了,現在這裡總結一下,以備自己以後用到注意。1.什麼是正規表示式的貪婪與非貪婪匹配 如 string str abcaxc patter p ab c 貪婪匹配 正規表示式一般趨向於最大長度匹配,也就是所謂的貪婪匹配。如上面使...

正規表示式 貪婪與非貪婪匹配

貪婪匹配與非貪婪匹配 貪婪匹配 預設情況下,正規表示式使用最長匹配原則 也叫貪婪匹配原則 例如 要將 zoom 中匹配 zo?的部 分替換成 r 替換的的結果是 rom 如果要將 zoom 中匹配 zo 的部分替換成 r 替換後的結果是 rm 非貪婪匹配 當字元?緊隨其他限定符 之後時,匹配模式變成...