我有一个制表符分隔的文件(包含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),但它也不起作用。
有关如何解决此问题的任何想法?任何帮助将受到高度赞赏。非常感谢!
答案 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