在Perl中逐行提取从文件中的特定字符开始的单词

时间:2013-12-31 16:15:53

标签: regex perl file

我首先要说的是我对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中。最终我将提取额外的价值观,如果有人能够在心里找到帮助这个贫穷,年轻,无知的程序员的话,我会非常感激!

2 个答案:

答案 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;
}