我首先要说的是我对Perl和正则表达式都是全新的,我从来都不是最好的伙伴。
我的问题是,我有一个充满行的文本文件。每行包含许多“单词”。这些单词可以包含字母,数字, - ,=等。除了空格之外几乎所有的东西。每个单词都用空格分隔。
在每一行中都有一个以三个独特字符开头的单词'mc ='。所以这个词可能是'mc = abcde123','mc = 12345hij','mc = blah'......你得到我的漂移。我想从每一行中提取这个单词并将它们插入到一个新的文本文件中。
#!/usr/bin/perl
use warnings;
my $input = 'input.txt';
my $output = 'output.txt';
open (FILE, "<", $input) or die "Can not open $input $!";
open my $out, '>' $output or die "Can not open $output $!";
while (<FILE>){
/(\s+mc=\/*S)/g;
print $out $_;
}
不确定这些代码对您有多大用处。我很清楚正则表达式是错误的 - 这只是将input.txt的全部内容打印到output.txt中。最终我将提取额外的价值观,如果有人能够在心里找到帮助这个贫穷,年轻,无知的程序员的话,我会非常感激!
答案 0 :(得分:4)
您唯一要匹配的是一个以mc=
开头的非空格字符串,前面是字符串或空格的开头。所以你想要的正则表达式是
/(?<!\S)(mc=\S*)/g
使用负向lookbehind断言(?<!\S)
是一种断言我们在关键字之前没有非空格的方法。我们不能使用(?<=\s|^)
(匹配空格或字符串的开头),因为lookbehind断言不能是可变长度,所以这是一种解决方法。
您可以使用例如:
perl -nle 'print for /(?<!\S)(mc=\S*)/g' input.txt > output.txt
一个单行程序,它将在每行的新行上打印匹配的字符串,并使用shell重定向(* nix shell)我们将单词打印到新文件。这将取代整个脚本。
您还可以使用以下内容修补自己的代码:
print $out $_ for /(?<!\S)(mc=\S*)/g;
但是我觉得,不需要对文件名进行硬编码,特别是当perl在这种情况下使用了很好的预定义功能时。
答案 1 :(得分:1)
#!/usr/bin/perl
use warnings;
my $input = 'input.txt';
my $output = 'output.txt';
open (FILE, "<", $input) or die "Can not open $input $!";
open my $out, '>' $output or die "Can not open $output $!";
while (<FILE>){
my @arr = /(?: ^|\s )(mc=\S*)/xg or next;
print $out "$_\n" for @arr;
}