[英]Save result from flip-flop in variable?
我有大約1kB來自STDIN的文字
my $f = join("", <STDIN>);
我open1
和close1
之間的內容,所以/open1/../close1/
。
我只看到它在while循環和$_
中的一個襯里和腳本中使用。
題
當所有內容都在$f
時,如何從我的腳本中獲取/open1/../close1/
的結果?
如果你想捕獲所有的線open1
和start1
標記(不包括標記),很容易用一個正則表達式來完成:
my $f = join("", <STDIN>);
my @matches = ( $f =~ m/\bopen1\b(.*?)\bclose1\b/gs );
for my $m (@matches) {
print "$m";
}
哪里
s
modifier將字符串視為單行; g
modifier捕獲所有匹配項; (.*?)
使用延遲量詞匹配一組任何字符 如果你想避免捕獲標記,范圍操作符(所謂的觸發器)對於這個任務來說不是很方便,因為像/open1/ .. /close1/
這樣的表達式對於匹配模式的行返回true 。
表達式/^open1$/ .. /^close1$/
返回false,直到/^open1$/
為true 。 一旦它匹配的線,並保持返回true,直到左正則表達式停止正在評估/^close1$/
變為真 。 當右表達式匹配時,重新啟動循環。 因此, open1
和close1
標記包含在$matches
。
如果輸入存儲在變量中,則更不方便,因為您需要逐行讀取變量的內容,例如:
my $matches = "";
my @lines = split /\n/, $f;
foreach my $line (@lines) {
if ($line =~ m/^open1$/ .. $line =~ m/^close1$/) {
$matches .= "$line\n";
}
}
注意,可以使用任意Perl表達式作為范圍運算符的操作數。 我不推薦這段代碼,因為它不是很有效,而且不太可讀。 同時,很容易使第一個示例適應open1
和close1
標記包含在匹配集中的情況,例如:
my @matches = ( $f =~ m/\bopen1\b(.*?)\bclose1\b/gs );
for my $m (@matches) {
print "open1${m}close1\n";
}
你可以重寫$f
的生成方式,以便它利用while
循環中的觸發器:
my ( $f, $matched );
while ( <> ) {
$f .= $_;
$matched .= $_ if /open1/ .. /close1/;
}
您也可以使用拆分 。 獲取第一對open1
和close1
之間的close1
my $open_to_close = (split /open1|close1/, $f)[1];
分隔符可以是open1
或close1
,因此返回的是三個元素的列表: open1
之前,它們之間和close1
之后。 我們采取第二個要素。
如果有更多open1
/ close1
對,則采用所有奇數索引元素。
也可以獲得陣列
my @parts = split /open1|close1/, $f;
my @all_open_to_close = @parts[ grep { $_ & 1 } 0..$#parts ];
或直接從列表中獲取
my @all_open_to_close =
grep { CORE::state $i; ++$i % 2 == 0 } split /open1|close1/, $f;
另一種方法是從$f
的內容中創建一個新的輸入流。
open my $fh, '<', \$f;
while (<$fh>) {
if (/open1/ .. /close1/) {
...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.