我在文件中有以下字符串
1. aaa bbb zccc ddd eee;
2. yyaaa bbb zccc dzdd eee; ('z' is present multiple times)
3. yyaaa bbb ccc *zddd eee; (special character '*' present)
4. yyaaa bbb ccc * zddd eee; (special character '*' present)
5. aaa bbb ccc* zddd eee; (special character '*' present)
6. aaa bbb ccc ddd eee; ('z' is absent)
另一个示例文件
1. aaa bbb zccc ddd eee;
2. yyaaa bbb zccc dzdd eee;
3. yyaaa bbb *ccc * zddd eee;
4. yyaaa bbb * ccc zddd eee;
5. aaa bbb* ccc zddd eee;
6. aaa bbb ccc ddd eee;
在每一行中,我想从aaa
的末尾提取子串到z
的第一个存在(减去z
)。如果z
不存在,则应打印整个字符串。如果有特殊字符,则应省略它们。
需要的输出
bbb
bbb
bbb ccc
bbb ccc
bbb ccc
aaa bbb ccc ddd eee
我已尝试过以下内容,但它没有提供我正在寻找的输出
my $file = qq(test.txt);
open (my $IN, '<', $file) || die "Cannot open $file for read: $!";
my @lines=<$IN>;
close($IN);
foreach (@lines)
{
if( $_ =~ m/aaa\b(.*?)z/)
{
print "$1\n";
}
}
我的输出
bbb
bbb
bbb ccc *
bbb ccc *
bbb ccc*
我不确定如何排除特殊字符(尝试过的字符类),并且它不会为没有'z'字符的第6行输出任何内容。
答案 0 :(得分:3)
我认为这就是你想要的
请注意,单个捕获中无法排除“特殊”字符,因此必须分两个阶段完成
你的“必需输出”比相应的输入行有更少的空格,但是你没有在文本中提到任何内容,所以无法知道你真正想要的是什么
use strict;
use warnings 'all';
while ( <DATA> ) {
next unless /a+\s+((?:(?!\s*z).)+)/;
(my $val = $1) =~ tr/*;//d;
print $val, "\n";
}
__DATA__
1. aaa bbb zccc ddd eee;
2. yyaaa bbb zccc dzdd eee;
3. yyaaa bbb *ccc * zddd eee;
4. yyaaa bbb * ccc zddd eee;
5. aaa bbb* ccc zddd eee;
6. aaa bbb ccc ddd eee;
bbb
bbb
bbb ccc
bbb ccc
bbb ccc
bbb ccc ddd eee
答案 1 :(得分:0)
您可以使用否定字符类
if( $_ =~ m/aaa\b([^z;]*)/)
{
$string = $1;
$string =~ s/\*//g;
print "$string\n";
}
# Outputs
# bbb
# bbb
# bbb ccc
# bbb ccc
# bbb ccc
# bbb ccc ddd eee
[^z;]*
匹配z
或;
$string =~ s/\*//g;
替换组中的*
。