打印$ 1 =〜S / - //在Perl

这将导致错误“的只读值的变形试图在......”

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

我如何做到这一点无需增加额外的线路? 据我可以告诉Perl没有内置str_replace()的功能。 我可以只写一个,但正如我所说,我试图找出如何做到这一点没有代码的其他行。

这不是正在一个真正的项目使用。 这仅被用于学习的目的。

--------------解决方案-------------

print( do { ( my $x = $1 ) =~ s/-//; $x }, "\n" );
print( ( apply { s/-// } $1 ), "\n" );
say( do { ( my $x = $1 ) =~ s/-//; $x } ); # 5.10+
say( apply { s/-// } $1 ); # 5.10+
say( $x =~ s/-//r ); # 5.14+

apply来源列表:: MoreUtils。

让我们退后一步

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

只是读$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

或使用转换操作符( tr/// )看到有什么本质regexy事情:

say for map tr!-!!dr , $mfgs =~ /.../g ;

两种方式将得到相同的结果,如果只有最多一连字符中的三个字符的块。 这是因为tr/-//dr将消除所有的连字符和s/-//r只删除第一次出现。



回答那人能怎么做,否则,让我们看看为什么没有工作之前

为什么不能$1进行修改?

perldoc perlvar (强调):

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

包含从相应的设置从上次成功的模式匹配捕获括号,这还不包括在已经被退出嵌套块匹配的模式的子模式。

这些变量只读和动态范围。

换句话说, $1不能被修改,这就是该s///试图做。

然而,副本$1 可以被修改 ,这是多少有些覆盖乔纳森莱弗勒的溶液。

我不知道为什么你要做到这一点 - 与比较的数据结构是次优:

my @mfgs = ( "AUD", "BMW", "CH", "FO", "TOY" );

然而,这种工作原理:

use strict;
use warnings;
my($mfgs, $x) = ("AUDBMWCH-FO-TOY");
while ($mfgs =~ /(.{3})/g)
{
printf "%s\n", ($x = $1, $x =~ s/-//, $x);
}

如果不狭窄或警告这样做,你可以使用:

my $mfgs = "AUDBMWCH-FO-TOY";
while ($mfgs =~ /(.{3})/g)
{
printf "%s\n", ($x = $1, $x =~ s/-//, $x);
}

不过,最好不要连打扰学习即可(AB)如何使用Perl不use strict;use warnings; (或者use diagnostics;中的作用)。

在Perl 5.14,有一个新的/r改性剂可用于s///取代(以及tr/// / y///音译),这将导致返回的结果是一个新的字符串,而不是改变原。

use 5.014;

$mfgs = "AUDBMWCH-FO-TOY";
while ($mfgs =~ /(.{3})/g) {
say $1 =~ s/-//r;
}

我如何做到这一点无需增加额外的线路? 据我可以告诉Perl没有内置str_replace()函数的功能。 我可以只写一个,但正如我所说,我试图找出如何做到这一点没有代码的其他行。

你看过perlfunc? 此外,这是不是功能,它是关于$1是只读变量。 见的perldoc perlvar。

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

包含从相应的设置从上次成功的模式匹配捕获括号,这还不包括在已经被退出嵌套块匹配的模式的子模式。

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



由于靠近我可以告诉大家,这是最经济的方式来实现问题的代码:

tr/-//d, say for $mfgs =~ /.{3}/g;

或长版本:

my $mfgs = "AUDBMWCH-FO-TOY";
for my $str ($mfgs =~ /.{3}/g) {
$str =~ tr/-//d;
say $str;
}

注意捕获括号未在此情况下,必需的。 从的perldoc perlop得到:

该/ G修饰符指定全球模式匹配 - 也就是说,匹配多次尽可能在字符串中。 它是如何表现取决于上下文。 在列表上下文,它返回任何捕获括号在正则表达式匹配字符串的列表。 如果没有括号,则返回所有匹配的字符串列表,因为,如果有围绕整个图案括号。

还注意到的区别whilefor (foreach) while将遍历它们出现(使用匹配/g在标量上下文),与隐式使用的\G断言,但它不会匹配存储在一个变量(除$1for能一次解压所有的比赛(使用/g在列表上下文中),以及比赛将在循环变量(指定别 ​​名$_在第一种情况下, my $str第二)。

在标量上下文中,m // G各自的执行找到了下一场比赛,返回true如果匹配,假如果没有进一步的匹配。 最后一场比赛后的位置可以读取或使用POS()函数来设置; 看到POS机。 一个失败的比赛通常复位到字符串的开头搜索位置,但你可以避免通过添加/ C修饰符(比如。M // GC)。 修改目标字符串也将把搜索位置。

你总是可以只是这样做让您的分隔符拆分项目的数组..

@a = split("-", $mfgs);

要str_replace函数使用

$var =~ s/search/replace/g;

像这样

$mfgs =~ s/-/\n/g;
printf("%s\n", $mfgs);

分类:正则表达式 时间:2015-03-15 人气:1
本文关键词: 正则表达式,PERL
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.299 (s). 10 q(s)