Perl:匹配制表符分隔文件中的确切单词

时间:2012-10-16 10:11:36

标签: regex perl tab-delimited-text

我有一个制表符分隔的文件(包含2列),格式如下:

ABA-1 (tab)           CDF@
ABA-1 (tab)           EFG
ZYA (tab)             ABA-1 this
EFG that this (tab)   ZYA

我想只匹配/ EFG /而不是/ EFG这个/。同样,我想只匹配/ ABA-1 /而不是/ ABA-1这个/.

以下模式不起作用:

$line=~ /^(\w*\-?\w*\@?)\t*(\w*\-?\w*\@?)$/

我尝试过使用单词边界(\ b),但它也不起作用。

有关如何解决此问题的任何想法?任何帮助将受到高度赞赏。非常感谢!

3 个答案:

答案 0 :(得分:3)

由于几个原因,你的正则表达式不起作用。首先,您的标签不能是可选的,否则该行将无法正确分割。其次,您的模式中没有任何内容可以说明之后要匹配的部分,即没有匹配that this的内容。

您可以在每次捕获后添加.*?来解决第一个问题(或者,对于第二次捕获,只需删除尾随的$锚点)。只需将\t*更改为\t即可解决第二个问题。

此修改适用于您的示例数据

$line =~ /^(\w*\-?\w*\@?).*?\t(\w*\-?\w*\@?).*?$/

但它不是很漂亮!

看起来你只想在标签或行首之后直接想要所有非空格字符串

该程序将该想法编码为正则表达式

use strict;
use warnings;

my @data = (
  "ABA-1\tCDF@",
  "ABA-1\tEFG", 
  "ZYA\tABA-1 this",
  "EFG that this\tZYA",
);

for (@data) {
  my @fields = /(?:^|\t)(\S+)/g;
  print "@fields\n";
}

<强>输出

ABA-1 CDF@
ABA-1 EFG
ZYA ABA-1
EFG ZYA

答案 1 :(得分:0)

这将匹配由一行上的单个标签分隔的两个单词(不包含空格):

$line=~ /^(\w+)\t(\w+)$/

更新:这将排除任何类似“ABA this”的行。但是,也许你想要从“ABA这个”中捕获ABA。这会为你做到这一点:

$line=~ /^([A-Z]+)[^\t]*\t([A-Z]+)/

更新:这是新要求的新模式。它匹配每列中的第一个非空白部分。

$line=~ /^([^\s]+).*\t\s*([^\s]+)/

答案 2 :(得分:0)

$line=~ /^(\w+)[^\t]*\t(\w+).*$/

这将只捕获tab之前和之后的第一个单词。

更新: - 如果您想在第一个空格之前匹配any non-space个字符,那么您可以尝试以下模式: -

my $line = "ABA-1\tCDF@";
my $line1 = "ZYA \t  ABA-1 this";

if ($line=~ /^([^\s]+)[^\t]*\t\s*([^\s]+).*$/) {    
    print "$1 $2";
}

if ($line=~ /^([^\s]+)[^\t]*\t\s*([^\s]+).*$/) {    
    print "$1 $2";
}

输出: -

ABA-1 CDF@
ZYA ABA-1