What is the best way to clear regex matching variables?

What is the best way to clear / reset all variables matching regular expressions?

  • An example of how $1not to reset between regular expression operations and uses the last match:

    $_="this is the man that made the new year rumble"; 
    / (is) /; 
    / (isnt) /; 
    say $1;          # outputs "is"
    
  • An example of how this can be problematic when working with loops:

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

Update: I did not think that I would need to do this, but example-2 is just an example. This question is about resetting matching variables, not the best way to implement them.

Despite this, initially my coding style was more strict with explicit and using if-blocks. Returning to this (example 2), it is now much easier to read many lines of code, I would find this syntax faster to understand.

+5
6

* reset . regex reset, , .

"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>. " ".

+14

, vars.

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

$1 .. , , . , .

+17

, . :

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 .

+5

:

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;
+1

( , ):

-:

: 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 version of `$1`.
$do1 = do { / (made) / && $1 };

print "\$1 == '$1'; \$do1 == '$do1'\n";  # -> $1 == 'is'; $do1 == 'made'
  • The advantage of this approach is that no current special regular expression variables are set or changed; the accepted answer, by contrast, changes variables such as $&and $'.
  • The disadvantage is that you must explicitly exclude the variables of interest; however, you get the result of the default mapping operation, and if you are only interested in the contents of the capture buffers, that will be enough.
+1
source

Assigning captures to the list behaves closer to what you think is needed.

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

All Articles