簡體   English   中英

清除正則表達式匹配變量的最佳方法是什么?

[英]What's the best way to clear regex matching variables?

清除/重置所有正則表達式匹配變量的最佳方法是什么?

  • 示例如何在正則表達式操作之間重置$1並使用最近的匹配:

     $_="this is the man that made the new year rumble"; / (is) /; / (isnt) /; say $1; # outputs "is" 
  • 舉例說明在使用循環時這可能會有什么問題:

     foreach (...){ /($some_value)/; &doSomething($1) if $1; } 

更新:我認為我不需要這樣做,但是例子2只是一個例子。 這個問題是關於重置匹配變量,而不是實現它們的最佳方法。

無論如何,最初我的編碼風格更明確並且使用if-blocks。 現在回到這個(例2)之后,閱讀許多行代碼會更加簡潔,我會發現這種語法更容易理解。

您應該使用匹配的返回值,而不是組變量的狀態。

foreach (...) {
    doSomething($1) if /($some_value)/;
}

如果比賽成功,$ 1等僅保證反映最近的比賽。 除了比賽成功后,你不應該看着他們。

正則表達式捕獲*由成功匹配重置。 要重置正則表達式捕獲,可以使用保證匹配的普通匹配操作。

"a" =~ /a/;  # Reset captures to undef.

是的,它看起來很奇怪,但你要求做一些奇怪的事情。

如果您修復了代碼,則不需要看起來很奇怪的解決方法 修復你的代碼甚至揭示了一個錯誤!

修正:

$_ = "this is the man that made the new year rumble"; 
if (/ (is) / || / (isnt) /) {
   say $1; 
} else{ 
   ...  # You're currently printing something random.
}

for (...) {
   if (/($some_pattern)/) {
      do_something($1);
   }
}

* - Backrefs是與之前捕獲的文本匹配的正則表達式模式。 例如\\1\\k<foo> 你實際上在談論“正則表達式捕獲緩沖區”。

您應該測試匹配是否成功。 例如:

foreach (...){
   /($some_value)/ or next;
   doSomething($1) if $1;
}

foreach (...){
   doSomething($1) if /($some_value)/ and $1;
}

foreach (...){
   if (/($some_value)/) {
      doSomething($1) if $1;
   }
}

根據$some_value內容,以及您希望如何處理匹配空字符串和/或0,您可能需要或可能不需要測試$1

你應該這樣做:

foreach (...) { 
   someFnc($1) if /.../; 
}

但如果你想堅持自己的風格,那么請檢查一下這個想法:

$_ = "this is the man that made the new year rumble";  

$m = /(is)/   ? $1 : undef;
$m = /(isnt)/ ? $1 : undef;

print $m, "\n" if defined $m;

補充現有的,有用的答案(以及通常在布爾上下文中測試匹配操作結果的明智建議,並且只有在測試成功時才采取行動):

根據您的方案,您可以采用不同的方式解決問題:

免責聲明:我不是一位經驗豐富的Perl程序員; 如果這種方法存在問題,請告訴我。

將匹配操作包含在do { ... }塊范圍內,將所有與正則表達式相關的特殊變量( $&$1 ,...)封裝到該塊中

因此, 您可以使用do { ... }來防止這些特殊變量首先被設置 (盡管來自塊之外的先前正則表達式操作的那些將顯然保持有效); 例如:

$_="this is the man that made the new year rumble"; 

# Match in current scope; -> $&, $1, ... *are* set.
/ (is) /;

# Match inside a `do` block; the *new* $&, $1, ... values
# are set only *inside* the block; 
# `&& $1` passes out the block's version of `$1`.
$do1 = do { / (made) / && $1 };

print "\$1 == '$1'; \$do1 == '$do1'\n";  # -> $1 == 'is'; $do1 == 'made'
  • 這種方法的優點是不會設置或更改當前作用域的特殊正則表達式變量; 相反,接受的答案會改變$&$'等變量。
  • 缺點是你必須明確傳出感興趣的變量; 但是,默認情況下會獲得匹配操作的結果,如果您只對捕獲緩沖區的內容感興趣,那就足夠了。

將捕獲分配給列表的行為更接近於您想要的內容。

for ("match", "fail") {
    my ($fake_1) = /(m.+)/;
    doSomething($fake_1) if $fake_1;
}

暫無
暫無

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

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