我需要替换 Subjects ex :- Subjects :***** 但它给出了输出 :- Subjects :***** Computer
I need to replace Subjects ex :- Subjects :***** but it is giving the output :- Subjects :*****Computer
在这里您可以看到我的代码正在用 *****
替换主题
但正在发生的事情是它没有取代第二行。
我一直在尝试这样做,但每次都失败了。如果有人可以帮助我,请查看
我想要的输出是:
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects :*****
Text : what ever happens to this code does not even matter to me
Time :*****
我得到的输出是:
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects :*****Computer
Text : what ever happens to this code does not even matter to me
Time :*****
代码如下:
my $fm_log= "
-------------------------------------------------------------------------------
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : Physics Chemistry Maths
Computer
Text : what ever happens to this code does not
even matter to me
Time : 10.304534
";
my %fm_info;
$fm_log =~ s!.*?(---------------)!!s;
$fm_log =~ s!vwmg.*!!sg;
my @fm_log = split(/-------+/, $fm_log);
@fm_log = grep {! m!^\s*$!s} @fm_log;
for (my $i = 0; $i < @fm_log;$i++){
my $type = undef;
my @tmp1 = split(/\R+/,$fm_log[$i]);
foreach (@tmp1)
{
$_ =~ s!^\s+!xxxx! if $_ !~ m!:!;
$_ =~ s!(Time\s+:)\s+.*!xxx!;
$_ =~ s!(Subjects\s+:)\s+.*!xxx!;
}
$fm_log[$i] = join("\n",@tmp1);
$fm_log[$i] =~ s!\R+xxxx!!mg;
}
print @fm_log;
你得到的原因
Subjects :*****Computer
而不是
Subjects :*****
是在换行符处拆分原始字符串 \R+
,然后编辑这些行,然后将字符串重新连接在一起。由于 Computer
换行,因此不会被编辑。
my @tmp1 = split(/\R+/,$fm_log[$i]); # <---- splitting the line
foreach (@tmp1) { # editing the pieces
$_ =~ s!^\s+!xxxx! if $_ !~ m!:!;
$_ =~ s!(Time\s+:)\s+.*!xxx!;
$_ =~ s!(Subjects\s+:)\s+.*!xxx!;
}
$fm_log[$i] = join("\n",@tmp1); # joining the pieces
换句话说,如果您有一个字符串,例如:
my $str = "foo: bar\nbaz";
然后在换行处拆分字符串并尝试删除 foo:
之后的所有内容
my @pieces = split /\R+/, $str;
现在 @pieces
将包含以下内容:
$VAR1 = [
'foo: bar',
'baz'
];
如果我们尝试用 s/foo:.*//
编辑它们,我们将永远不会影响原始字符串的 baz
部分。
由于您的文件包含由以单词开头、后跟冒号的行分隔的字段,然后是可能包含换行符的内容,因此您需要首先将字段彼此分开。
您的字段看起来像...
TITLE : CONTENT
CONTENT ...
TITLE : CONTENT ...
可能有读取这种格式的模块更适合。我编写了这个快速 hack 来将数据强制转换为散列,您可以在其中通过简单地为字段分配新值来编辑字段。
use strict;
use warnings;
use Data::Dumper;
my $fm_log= " Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : Physics Chemistry Maths
Computer
Text : what ever happens to this code does not
even matter to me
Time : 10.304534
";
my @info = split /^ *([\w ]+) : /m, $fm_log; # split into fields
s/\s+/ /g for @info; # cleanup start
s/^\s+|\s+$// for @info;
shift @info; # cleanup complete
my %info = @info;
print Dumper \%info; # show the data structure we made
$info{Subjects} = "****";
$info{Time} = "****";
printf("%s : %s\n", $_, $info{$_}) for qw(Name Class Stream Subjects Text Time);
这将输出
$VAR1 = {
'Class' => '12th',
'Stream' => 'Science',
'Time' => '10.304534',
'Subjects' => 'Physics Chemistry Maths Computer',
'Text' => 'what ever happens to this code does not even matter to me',
'Name' => 'Piyush Prasad'
};
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : ****
Text : what ever happens to this code does not even matter to me
Time : ****
在这里您可以看到我的代码正在用 *****
替换主题
但正在发生的事情是它没有取代第二行。
我一直在尝试这样做,但每次都失败了。如果有人可以帮助我,请查看
我想要的输出是:
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects :*****
Text : what ever happens to this code does not even matter to me
Time :*****
我得到的输出是:
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects :*****Computer
Text : what ever happens to this code does not even matter to me
Time :*****
代码如下:
my $fm_log= "
-------------------------------------------------------------------------------
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : Physics Chemistry Maths
Computer
Text : what ever happens to this code does not
even matter to me
Time : 10.304534
";
my %fm_info;
$fm_log =~ s!.*?(---------------)!!s;
$fm_log =~ s!vwmg.*!!sg;
my @fm_log = split(/-------+/, $fm_log);
@fm_log = grep {! m!^\s*$!s} @fm_log;
for (my $i = 0; $i < @fm_log;$i++){
my $type = undef;
my @tmp1 = split(/\R+/,$fm_log[$i]);
foreach (@tmp1)
{
$_ =~ s!^\s+!xxxx! if $_ !~ m!:!;
$_ =~ s!(Time\s+:)\s+.*!xxx!;
$_ =~ s!(Subjects\s+:)\s+.*!xxx!;
}
$fm_log[$i] = join("\n",@tmp1);
$fm_log[$i] =~ s!\R+xxxx!!mg;
}
print @fm_log;
你得到的原因
Subjects :*****Computer
而不是
Subjects :*****
是在换行符处拆分原始字符串 \R+
,然后编辑这些行,然后将字符串重新连接在一起。由于 Computer
换行,因此不会被编辑。
my @tmp1 = split(/\R+/,$fm_log[$i]); # <---- splitting the line
foreach (@tmp1) { # editing the pieces
$_ =~ s!^\s+!xxxx! if $_ !~ m!:!;
$_ =~ s!(Time\s+:)\s+.*!xxx!;
$_ =~ s!(Subjects\s+:)\s+.*!xxx!;
}
$fm_log[$i] = join("\n",@tmp1); # joining the pieces
换句话说,如果您有一个字符串,例如:
my $str = "foo: bar\nbaz";
然后在换行处拆分字符串并尝试删除 foo:
my @pieces = split /\R+/, $str;
现在 @pieces
将包含以下内容:
$VAR1 = [
'foo: bar',
'baz'
];
如果我们尝试用 s/foo:.*//
编辑它们,我们将永远不会影响原始字符串的 baz
部分。
由于您的文件包含由以单词开头、后跟冒号的行分隔的字段,然后是可能包含换行符的内容,因此您需要首先将字段彼此分开。
您的字段看起来像...
TITLE : CONTENT
CONTENT ...
TITLE : CONTENT ...
可能有读取这种格式的模块更适合。我编写了这个快速 hack 来将数据强制转换为散列,您可以在其中通过简单地为字段分配新值来编辑字段。
use strict;
use warnings;
use Data::Dumper;
my $fm_log= " Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : Physics Chemistry Maths
Computer
Text : what ever happens to this code does not
even matter to me
Time : 10.304534
";
my @info = split /^ *([\w ]+) : /m, $fm_log; # split into fields
s/\s+/ /g for @info; # cleanup start
s/^\s+|\s+$// for @info;
shift @info; # cleanup complete
my %info = @info;
print Dumper \%info; # show the data structure we made
$info{Subjects} = "****";
$info{Time} = "****";
printf("%s : %s\n", $_, $info{$_}) for qw(Name Class Stream Subjects Text Time);
这将输出
$VAR1 = {
'Class' => '12th',
'Stream' => 'Science',
'Time' => '10.304534',
'Subjects' => 'Physics Chemistry Maths Computer',
'Text' => 'what ever happens to this code does not even matter to me',
'Name' => 'Piyush Prasad'
};
Name : Piyush Prasad
Class : 12th
Stream : Science
Subjects : ****
Text : what ever happens to this code does not even matter to me
Time : ****