[英]Why perl regex '*?' stay greedy?
我運行一個簡單的程序:
my $_ = '/login/.htaccess/.htdf';
s!(/\.ht.*?)$!/!;
print "$_ $1";
OUT
/login/ /.htaccess/.htdf
我希望這個正則表達式只匹配/.htdf
。
例2:
my $_ = 'abcbc';
m/(b.*?)$/;
print "$_ $1\n";
OUT
abcbc bcbc
我期待bc
。
為什么*?
仍然貪心? (我想要最小的比賽。)
原子按順序匹配,第一個原子之后的每個原子必須在前一個原子離開匹配的位置匹配。 (第一個原子隱含地以\\A(?s:.)*?
。)這意味着.*
.*?
沒有決定它開始匹配的地方; 它只能決定它停止匹配的地方。
這並不貪心。 \\.ht
帶來比賽進行到位置10和10位 ,最小.*?
可以匹配並且仍然具有模式匹配的其余部分是access/.htdf
。 事實上,這是唯一的事情.*?
可以匹配位置10並且仍然具有其余的模式匹配。
我想你想刪除路徑的最后一部分,如果它以.ht
開頭,留下前面的/
就位。 為此,您可以使用以下任一方法:
s{/\.ht[^/]*$}{/}
要么
s{/\K\.ht[^/]*$}{}
這並不貪心。 b
將匹配帶到位置2, 在位置2帶到最小值.*?
可以匹配並且仍然有其余的模式匹配是cbc
。 事實上,這是唯一的事情.*?
可以匹配位置2並且仍然具有其余的模式匹配。
你可能正在尋找
/b[^b]*$/
要么
/b(?:(?!b).)*$/ # You'd use this if "b" was really more than one char.
您可以使用負向前瞻:
~/(\.ht(?!.*\.ht).*)$~
(?!.*\\.ht)
是負先行是確保沒有.ht
后發生.ht
從而確保只有最后.ht
匹配。
.*?
如果右邊有一些模式,那將是非貪婪的。
碼:
$str = '/login/.htaccess/.htdf';
$str =~ s~/(\.ht(?!.*\.ht).*)$~/~m;
print "$str\n";
為什么不呢? 貪婪是向前的,而不是向后的。 在非貪婪模式下,狀態機開始匹配並在每一步進行檢查,而不是僅僅對其進行全部篡改然后回溯,但這並不能保證您的“最小匹配”。
也許你可能想避免匹配/
? 就像在s{/\\.ht[^/]*$}{/}
。
正則表達式就像你已經成功一樣。
但是如果你想使用點元字符,那一定是貪心的。
這應該工作s!.*/\\K\\.ht.*$!!
它基本上會結束.ht...
如果你想具體,你需要s!/\\K\\.htdf$!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.