簡體   English   中英

為什么perl regex'*?' 保持貪心?

[英]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:.)*? 。)這意味着.* .*? 沒有決定它開始匹配的地方; 它只能決定它停止匹配的地方。

例1

這並不貪心。 \\.ht帶來比賽進行到位置10和10位 ,最小.*? 可以匹配並且仍然具有模式匹配的其余部分是access/.htdf 事實上,這是唯一的事情.*? 可以匹配位置10並且仍然具有其余的模式匹配。

我想你想刪除路徑的最后一部分,如果它以.ht開頭,留下前面的/就位。 為此,您可以使用以下任一方法:

s{/\.ht[^/]*$}{/}

要么

s{/\K\.ht[^/]*$}{}

例2

這並不貪心。 b將匹配帶到位置2, 在位置2帶到最小值.*? 可以匹配並且仍然有其余的模式匹配是cbc 事實上,這是唯一的事情.*? 可以匹配位置2並且仍然具有其余的模式匹配。

你可能正在尋找

/b[^b]*$/

要么

/b(?:(?!b).)*$/    # You'd use this if "b" was really more than one char.

您可以使用負向前瞻:

~/(\.ht(?!.*\.ht).*)$~

RegEx演示

(?!.*\\.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM