我是Perl的新手,我想知道是否有人可以帮助我。
我有这样的输入:
a,b,
c,d,e,f,g,h,
i,j,q // Letras
我试图分别在//
之前获取字母,然后在{}
之间以:
分隔。{/ p>
我尝试了这个RE ([\w,;:\s\t]*)(\n|\/\/)/m
,我可以在$1
中获取每一行的所有字母(作为包含分隔符的字符串),但不是我想要的。
我需要在同一个文件中多次匹配该模式,因此我使用的是/g
。
编辑:
这是我的代码块:
while ( <> ) {
if ( /([\w,;:\s\t]*)(\n|\/\/)/m ) {
print "$1\n";
}
}
答案 0 :(得分:2)
/m
用于使用^
和$
来匹配多行中字符串中的行。
另一方面,您正在逐行阅读输入 。如果您一次只查看一行,则不能指望使用单个表达式跨行匹配。
相反,通过将$/
设置为适当的值来读取块。如果块总是以精确的字符串"// Letras\n\n"
结束,则任务更简单。
#!/usr/bin/env perl
use strict;
use warnings;
local $/ = '//';
while (my $chunk = <DATA>) {
chomp $chunk;
my @fields = ($chunk =~ /([a-z])[, ]/g);
next unless @fields;
printf "{%s}\n", join(':', @fields);
}
__DATA__
a,b,
c,d,e,f,g,h,
i,j,q // Letras
a,b,
c,d,e,f,g,h,
i,j,q // Metras
输出:
{a:b:c:d:e:f:g:h:i:j:q} {a:b:c:d:e:f:g:h:i:j:q}
您还可以使用File::Stream:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Stream;
my $stream = File::Stream->new(
\*DATA,
separator => qr{ (?: \s+ // [^\n]+ ) \n\n }x
);
while (my $chunk = <$stream>) {
$chunk =~ s{ \s+ // .* \z }{}sx;
$chunk =~ s{ ,\n? }{:}gx;
print "{$chunk}\n";
}
__DATA__
a,b,
c,d,e,f,g,h,
i,j,q // Letras
a,b,
c,d,e,f,g,h,
i,j,q // Metras
答案 1 :(得分:1)
我认为你的目标是从每一行中删除注释(用双斜杠表示),然后用大括号括起来,并用冒号{{1分隔符而不是逗号
首先,您应该使用:
然后您需要删除任何结尾的评论chomp
。这也会删除s|\s*//.*||
之前的所有空格。我使用管道符//
作为分隔符,以避免必须在正则表达式模式中转义斜杠。并且数据一次处理一行,因此不需要全局 |
修饰符
此程序从命令行中指定的文件中读取,我已将其设置为包含您在问题中显示的数据
/g
<强>输出强>
use strict;
use warnings;
while ( <DATA> ) {
chomp;
s|\s*//.*||;
print "{$_}\n";
}
<强>更新强>
感谢Sinan Ünür's solution我注意到您已经要求&#34;在[{1}}之间打印[{1}} {a,b,}
{c,d,e,f,g,h,}
{i,j,q}
&#34; < / em>的
这是对上面{}
循环的修改,它会查找当前行中不包含逗号的所有子字符串,并使用冒号:
再次将它们连接在一起
while
<强>输出强>
:
我确信真正的解决方案要简单得多,但除非你详细说明你的问题,否则我们必须迎合所有可能性
答案 2 :(得分:0)
您是否希望将所有3行的字母组合到输出中,或转换每行?
换句话说,是您想要的输出
{a:b}
{c:d:e:f:g:h}
{i:j:q}
或
{a:b:c:d:e:f:g:h:i:j:q}
如果你想要前者,鲍罗丁的回答是可行的。 如果你想要后者,那么你应该将内容加载到一个数组中,并使用join语句打印它。为此,我修改了鲍罗丁的答案:
while ( <> ) { # read each line
chomp; # remove \n from line
s|\s*//.*||; # remove comment
push @values, ':', /[^,]+/g; # store letters in array
}
my $values = join ':', @values; # convert array to string
print "{$values}\n"; # print the results
答案 3 :(得分:0)
my $str = "a,b,
c,d,e,f,g,h,
i,j,q // Letras";
$str = join "",map {s/,/:/g ;(split)[0]} split '\n', $str;
print "{$str}";
Sample output
{a:b:c:d:e:f:g:h:i:j:q}
我正在考虑一个由换行符分隔的多行的字符串。
join "",map {s/,/:/g ;(split)[0]} split '\n', $str
这是从右到左评估的。
在\n
上与$str
分开,会产生3个元素,这些元素是map
的输入。
(split)[0]
:split
的默认分隔符是空格。所以每个元素都被拆分为空格,而0th
元素只被视为丢弃其他元素。
(split)[0]
的Ex i,j,q // Letras
产生3个元素“i,j,q”“//”“Letras”,其中只考虑元素0即“i,j,q”。
,
已替换为:
join
用于合并map
中的所有结果元素。