簡體   English   中英

將觸發器的結果保存在變量中?

[英]Save result from flip-flop in variable?

我有大約1kB來自STDIN的文字

my $f = join("", <STDIN>);

open1close1之間的內容,所以/open1/../close1/

我只看到它在while循環和$_中的一個襯里和腳本中使用。

當所有內容都在$f時,如何從我的腳本中獲取/open1/../close1/的結果?

使用單個正則表達式捕獲所有匹配項

如果你想捕獲所有的線open1start1標記(不包括標記),很容易用一個正則表達式來完成:

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$/變為 當右表達式匹配時,重新啟動循環。 因此, open1close1標記包含在$matches

如果輸入存儲在變量中,則更不方便,因為您需要逐行讀取變量的內容,例如:

my $matches = "";
my @lines = split /\n/, $f;
foreach my $line (@lines) {
  if ($line =~ m/^open1$/ .. $line =~ m/^close1$/) {
    $matches .= "$line\n";
  }
}

注意,可以使用任意Perl表達式作為范圍運算符的操作數。 我不推薦這段代碼,因為它不是很有效,而且不太可讀。 同時,很容易使第一個示例適應open1close1標記包含在匹配集中的情況,例如:

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/;
}

您也可以使用拆分 獲取第一對open1close1之間的close1

my $open_to_close = (split /open1|close1/, $f)[1];

分隔符可以是open1close1 ,因此返回的是三個元素的列表: 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;

v5.10一個功能 如果您已經use它,則不需要CORE::前綴。

另一種方法是從$f的內容中創建一個新的輸入流。

open my $fh, '<', \$f;
while (<$fh>) {
    if (/open1/ .. /close1/) {
        ...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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