正則運算式s/\A\s*\n//從字串的開頭洗掉每個全空白行。它保留了其他所有內容,包括可能開始第一條可見行的任何空白。“可見線”是指滿足/\S/. 下面的代碼演示了這一點。
但它是如何作業的?
\A 錨定字串的開頭
\s*貪婪地搶占所有空白。但是如果沒有(?s)修飾符,它應該停在第一行的末尾,不是嗎?請參閱
https://perldoc.perl.org/perlre。
假設沒有(?s)修飾符,它仍然“將字串視為單行”。然后我希望貪婪\s*者抓住它看到的每個空白字符,包括換行符。因此,它會傳遞“dogs”字串之前的換行符,繼續抓取空格,遇到“d”,我們將永遠無法匹配。
盡管如此,代碼完全符合我的要求。由于我無法解釋它,它就像一個雜亂無章的東西,碰巧起作用,通過反復試驗發現。它起作用的原因是什么?
#!/usr/bin/env perl
use strict; use warnings;
print $^V; print "\n";
my @strs=(
join('',"\n", "\t", ' ', "\n", "\t", ' dogs',),
join('',
"\n",
"\n\t\t\x20",
"\n\t\t\x20",
'......so what?',
"\n\t\t\x20",
),
);
my $count=0;
for my $onestring(@strs)
{
$count ;
print "\n$count ------------------------------------------\n";
print "|$onestring|\n";
(my $try1=$onestring)=~s/\A\s*\n//;
print "|$try1|\n";
}
uj5u.com熱心網友回復:
但它是如何作業的?
...
我希望貪婪的 \s* 抓住它看到的每個空白字符,包括換行符。因此,它會傳遞“dogs”字串之前的換行符,繼續抓取空格,遇到“d”,我們將永遠無法匹配。
正確 -\s*首先抓取d(in dogs) 之前的所有內容,然后匹配將失敗......所以它會備份,一次一個字符,縮短貪婪的抓取,以便為以下模式提供機會,在這里\n, 匹配。
這有效!所以\s*匹配到 (last!) \n,那個匹配\n模式中的以下內容,一切都很好。那被洗掉了,我們留下"\tdogs"來列印。
這稱為回溯。也可以在 perlretut 中查看。回溯可以被抑制,最顯著的是通過所有形式,或者更確切地說是通過擴展構造(?>...)。
但是沒有 (?s) 修飾符,它應該停在第一行的末尾,不是嗎?
在這里,您可能會產生混淆\s與.,這的確不符合\n(無/s)
uj5u.com熱心網友回復:
這里有兩個問題。
第一個是關于\s和(缺乏)的相互作用(?s)。很簡單,沒有互動。
\s匹配空格字符,包括換行符 (LF)。它不受(?s)任何影響。
(?s)只影響..
(?-s)導致.匹配除 LF 之外的所有字符。[默認](?s)導致.匹配所有字符。
如果想匹配當前行上的空格,可以使用\h代替\s。它只匹配水平空白,因此不包括 CR 和 LF(等等)。
或者,(?[ \s - \n ])[1]、[^\S\n][2]和\s(?<!\n)[3]都匹配除 LF 之外的空白字符。
第二個是關于貪婪意味著什么的誤解。
貪婪或缺乏,不影響,如果一個模式可以匹配,只是什么它匹配。例如,對于給定的輸入,/a /和/a ?/都會匹配,或者都不匹配。一個匹配而不匹配另一個是不可能的。
"aaaa" =~ /a / # Matches 4 characters at position 0.
"aaaa" =~ /a ?/ # Matches 1 character at position 0.
"bbbb" =~ /a / # Doesn't match.
"bbbb" =~ /a ?/ # Doesn't match.
當某事物貪婪時,這意味著它將在當前位置匹配最多的可能,從而允許整個模式匹配。以以下為例:
"ccccd" =~ /.*d/
這種模式可以通過.*match onlycccc而不是ccccd,從而實作匹配。這是通過回溯實作的。.*最初匹配ccccd,然后發現d不匹配,因此.*僅嘗試匹配cccc。這允許d匹配整個模式。
您也會發現在貪婪之外使用回溯。"efg" =~ /^(e|.f)g/匹配,因為它g在使用第一個選項時無法匹配時嘗試第二個選項。
與前面示例中.*避免匹配 的方式相同,避免匹配d示例中\s*之前的 LF 和制表符dog。
- 目前需要
use experimental qw( regex_sets );,但我認為它是安全的。 - 不太清楚,因為它使用雙重否定。
[^\S\n]
= 一個字符 ( not( not(\s) 或 LF ) )
= 一個字符 ( not(not(\s)) 和 not(LF) )
= 一個字符 ( \s 而不是 LF ) - 效率較低,遠沒有正則運算式集那么漂亮。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316099.html
