2

次の形式のタブ区切りファイル (2 列を含む) があります。

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

/EFG/ のみに一致させ、/EFG that this/ には一致させたくありません。同様に、/ABA-1/ のみに一致させ、/ABA-1 this/ には一致させたくありません。

次のパターンは機能しません。

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

単語境界 (\b) を使用してみましたが、どちらも機能しません。

この問題に取り組む方法についてのアイデアはありますか? どんな助けでも大歓迎です。どうもありがとう!

4

3 に答える 3

3

あなたの正規表現は、いくつかの理由で機能しません。まず、タブをオプションにすることはできません。そうしないと、行が適切に分割されません。第二に、あなたのパターンには、一致させたい部分のthat thisに可能な文字を説明するものは何もありません。つまり、一致するものは何もありません。

最初のものは、各キャプチャの後に追加することで解決できます.*?(または、2 番目のキャプチャの場合は、末尾の$アンカーを削除するだけです)。\t*2 番目の問題は、に変更するだけで修正され\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
于 2012-10-16T10:41:32.490 に答える
1

これは、1 行の 1 つのタブで区切られた 2 つの単語 (スペースを含まない) に一致します。

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

更新: 「ABA this」のような行を除外します。ただし、「ABA this」から ABA だけをキャプチャしたい場合もあります。これはあなたのためにそれを行います:

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

更新:これは、新しい要件の新しいパターンです。各列の最初の非空白部分に一致します。

$line=~ /^([^\s]+).*\t\s*([^\s]+)/
于 2012-10-16T10:16:18.390 に答える
1
$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
于 2012-10-16T10:21:12.447 に答える