Perl:捕获变量不能设置为undef?
Perl: Capturing variable cannot be set undef?
我有几个捕获的正则表达式,显然捕获变量保留了最后一个有效捕获的值:
# Two scalars to use for regexp
$x = 'abc';
$y = 'def';
# first regexp
$x =~ /^(ab)/;
$x = ;
# second regexp
$y =~ /^(de)/;
$y = ;
print \"$x\n$y\";
输出为:
ab
de
这里是单行版:
perl -e "$x='abc'; $y='def'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
如果$y='def'
改为$y='zdef'
:
perl -e "$x='abc'; $y='zdef'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
输出为:
ab
ab
如果我想在$x=
之后设置=undef
来移除$1
中的当前值
perl -e "$x='abc'; $y='zdef'; $x =~ /^(ab)/; $x=; =undef; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
输出为:
Modification of a read-only value attempted at -e line 1.
显然,捕获变量无法更改。
我想知道如何解决这个问题。我想要的结果是:
ab
..
其中 ..
表示“空”。就像在第一个正则表达式是 undef ($x='zabc
):
的情况下一样
perl -e "$x='zabc'; $y='def'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
..
de
您需要小心使用捕获变量 </code>(以及 <code>
、</code> 等)。它们在成功的模式匹配(和未分配)时分配,因此您必须确保您有正确的匹配。
<code>man perlvar
状态(强调成功):
$<digits> (, , ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match, ...
通常,您会这样做:
if ('abc' =~ /^(ab)/) {
$x = ;
}
if ('zdef' =~ /^(de)/) {
$y = ;
}
这样,您就不会得到错误的赋值。
但是,还有其他方法可以做到这一点。模式匹配本身给出一个 return 值,这取决于上下文。
$n = 'abc' =~ /^(ab)/; # $n = 1 for "true". This is scalar context
($n) = 'abc' =~ /^(ab)/; # $n = 'ab', the captured string. This is list context
$n = () = 'abc' =~ /(.)/g; # $n = 3, for 3 matches. /g gives multiple matches
($f, $g) = 'abc' =~ /(.)/g; # $f = 'a', $g = 'b'. List context
perl 正则表达式使用全局变量很常见。
而如果没有捕获,$1将是最后一个成功捕获的组。
正如我所说,这很常见,这也是 perl 的工作方式。
你能做什么?
首先,让所有捕获的组像这样排列:
@captures = $y =~ /^(de)/;
然后使用它。
二、使用ternar语句:
$y = $y =~ /(ho)/ ? : undef;
或者你可以考虑这个套餐https://metacpan.org/pod/Regex::Object
它有助于解决这类问题。但是您需要一些关于 CPAN 和对象的基本知识。
替换
$y =~ /^(de)/;
$y = ;
与
( $y ) = $y =~ /^(de)/;
或
$y = $y =~ /^(de)/ ? : undef;
前者依赖于匹配运算符 returns 它在列表上下文中调用时捕获的序列这一事实。
后者依赖于匹配运算符 returns 在标量上下文中调用时匹配是否成功的事实。
我有几个捕获的正则表达式,显然捕获变量保留了最后一个有效捕获的值:
# Two scalars to use for regexp
$x = 'abc';
$y = 'def';
# first regexp
$x =~ /^(ab)/;
$x = ;
# second regexp
$y =~ /^(de)/;
$y = ;
print \"$x\n$y\";
输出为:
ab
de
这里是单行版:
perl -e "$x='abc'; $y='def'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
如果$y='def'
改为$y='zdef'
:
perl -e "$x='abc'; $y='zdef'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
输出为:
ab
ab
如果我想在$x=
之后设置=undef
来移除$1
perl -e "$x='abc'; $y='zdef'; $x =~ /^(ab)/; $x=; =undef; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
输出为:
Modification of a read-only value attempted at -e line 1.
显然,捕获变量无法更改。
我想知道如何解决这个问题。我想要的结果是:
ab
..
其中 ..
表示“空”。就像在第一个正则表达式是 undef ($x='zabc
):
perl -e "$x='zabc'; $y='def'; $x =~ /^(ab)/; $x=; $y =~ /^(de)/; $y=; print \"$x\n$y\";"
..
de
您需要小心使用捕获变量 </code>(以及 <code>
、</code> 等)。它们在成功的模式匹配(和未分配)时分配,因此您必须确保您有正确的匹配。
<code>man perlvar
状态(强调成功):
$<digits> (, , ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match, ...
通常,您会这样做:
if ('abc' =~ /^(ab)/) {
$x = ;
}
if ('zdef' =~ /^(de)/) {
$y = ;
}
这样,您就不会得到错误的赋值。
但是,还有其他方法可以做到这一点。模式匹配本身给出一个 return 值,这取决于上下文。
$n = 'abc' =~ /^(ab)/; # $n = 1 for "true". This is scalar context
($n) = 'abc' =~ /^(ab)/; # $n = 'ab', the captured string. This is list context
$n = () = 'abc' =~ /(.)/g; # $n = 3, for 3 matches. /g gives multiple matches
($f, $g) = 'abc' =~ /(.)/g; # $f = 'a', $g = 'b'. List context
perl 正则表达式使用全局变量很常见。 而如果没有捕获,$1将是最后一个成功捕获的组。
正如我所说,这很常见,这也是 perl 的工作方式。
你能做什么? 首先,让所有捕获的组像这样排列:
@captures = $y =~ /^(de)/;
然后使用它。
二、使用ternar语句:
$y = $y =~ /(ho)/ ? : undef;
或者你可以考虑这个套餐https://metacpan.org/pod/Regex::Object 它有助于解决这类问题。但是您需要一些关于 CPAN 和对象的基本知识。
替换
$y =~ /^(de)/;
$y = ;
与
( $y ) = $y =~ /^(de)/;
或
$y = $y =~ /^(de)/ ? : undef;
前者依赖于匹配运算符 returns 它在列表上下文中调用时捕获的序列这一事实。
后者依赖于匹配运算符 returns 在标量上下文中调用时匹配是否成功的事实。