在perl中打印$ 1 = ~s/ - //

Dre*_*pin 0 regex perl

这会导致错误"在......处修改只读值"

$mfgs = "AUDBMWCH-FO-TOY";
while( $mfgs =~ /(.{3})/g ) {
    print $1 =~ s/-// . "\n";
}
Run Code Online (Sandbox Code Playgroud)

如何在不添加额外行的情况下执行此操作?到目前为止,我可以告诉Perl没有内置str_replace()功能.我可以写一个,但正如我所说,我试图找出如何做到这一点,没有额外的代码行.

这不是在实际项目中使用.这仅用于学习目的.



Zai*_*aid 6

我们退一步吧

$mfgs = "AUDBMWCH-FO-TOY";
while( $mfgs =~ /(.{3})/g ) {
    print $1 =~ s/-// . "\n";
}
Run Code Online (Sandbox Code Playgroud)

只是一次读取$mfgs字符串三个字符并删除连字符.

人们可以重写如下:

say for map { s|-||r }  $mfgs =~ /.../g ; # Works in Perl 5.14+

use List::MoreUtils 'apply';
say for apply { s|-|| } $mfgs =~ /.../g ; # If that 'r' flag isn't there
Run Code Online (Sandbox Code Playgroud)

或使用音译操作符(tr///)看到没有任何固有的regexy进行:

say for map tr!-!!dr , $mfgs =~ /.../g ;
Run Code Online (Sandbox Code Playgroud)

如果在三个字符的块中最多只有一个连字符,则两种方式都会给出相同的结果.这是因为tr/-//dr会删除所有连字符,并s/-//r仅删除第一次出现的连字符.


这回答了人们如何做到这一点,所以让我们看看为什么它以前没有工作

为什么不能$1修改?

perldoc perlvar(重点补充):

$<digits> ($1, $2, ...)

包含来自上一次成功模式匹配的相应捕获括号集的子模式,不包括已经退出的嵌套块中匹配的模式.

这些变量是只读的和动态范围的.

换句话说,$1无法修改,这是s///尝试做的事情.

但是,$1 可以修改副本,这在Jonathan Leffler的解决方案中有所涉及.