2009-05-20 4 views
1

私はファイルを解析していて、それの部分は、レコードのことですが、フォーマットは同様である:正規表現のリストをどのように一致させるのですか?

CategoryA-- 
5: UserA 
6: UserB 
7: UserC 
CategoryB-- 
4: UserA 
5: UserB 

私がどのように見えるハッシュにそれを移動したい:

どう
{ UserA => { CategoryA => 5, CategoryB => 4, }, 
    UserB => { CategoryA => 6, CategoryB => 5, }, 
    UserC => { CategoryA => 7, }, 
} 

私はこれに正規表現をするのですか?

編集:これは純粋に正規表現である必要はありません。perlとループだけで良いでしょう。

+3

これは、少なくともそれ自身ではなく、正規表現の仕事ではありません。ループも必要です。 –

+0

すでにいくつかのコードがありましたか?どのような正規表現を期待していますか?完全なカテゴリーセクションと一致する1つのラインに一致するものはありますか? – innaM

+0

純粋な正規表現である必要はありません。 – Timmy

答えて

5

新しいカテゴリを識別するために1つ、ユーザーレコードを解析するために2つの正規表現が必要です。

#!/usr/bin/perl 

use strict; 
use warnings; 

my %users; 
my $cur; 
while (<DATA>) { 
    if (my ($category) = /^(.*)--$/) { 
     $cur = $category; 
     next; 
    } 
    next unless my ($id, $user) = /([0-9]+): (\w+)/; 
    die "no category found" unless defined $cur; 
    $users{$user}{$cur} = $id; 
} 

use Data::Dumper; 
print Dumper \%users; 

__DATA__ 
CategoryA-- 
5: UserA 
6: UserB 
7: UserC 
CategoryB-- 
4: UserA 
5: UserB 

それとも、あなたはPerl 5.10以降を持っている場合、あなたは1つの正規表現で指定キャプチャを使用することができます。

#!/usr/bin/perl 

use 5.010; 
use strict; 
use warnings; 

my %users; 
my $cur; 
while (<DATA>) { 
    next unless /^(?:(?<category>.*)--|(?<id>[0-9]+): (?<user>\w+))$/; 
    if (exists $+{category}) { 
     $cur = $+{category}; 
     next; 
    } 
    die "no category found" unless defined $cur; 
    $users{$+{user}}{$cur} = $+{id}; 
} 

use Data::Dumper; 
print Dumper \%users; 

__DATA__ 
CategoryA-- 
5: UserA 
6: UserB 
7: UserC 
CategoryB-- 
4: UserA 
5: UserB 
+1

入力レコードセパレータを " - \ n"に変更することで、これをもっと簡単にすることができます。 –

+0

@newt: " - \ n"シーケンスはレコードの終わりをマークしません。 $ /に設定するとCategoryAのデータはなくなり、CategoryAのデータはCategoryBのグループになります。 –

+0

@newt私はこれをやって、ループの前にポンプをプライミングすることを考えましたが、2つの正規表現が理解しやすいと決めました。 –

0

これはあなたのためにそれを分割します。

prompt> ruby e.rb 
[["CategoryA--", nil, nil], [nil, "5", "UserA"], [nil, "6", "UserB"], [nil, "7", "UserC"], ["CategoryB--", nil, nil], [nil, "4", "UserA"], [nil, "5", "UserB"]] 
prompt> cat e.rb 
s = <<TXT 
CategoryA-- 
5: UserA 
6: UserB 
7: UserC 
CategoryB-- 
4: UserA 
5: UserB 
TXT 
p s.scan(/(^.*--$)|(\d+): (.*$)/) 
prompt> 
3

このperlコードは、あなたの探しているもの(主に1つの変更)を行うようです。私はデータ構造を少し違った形にしましたが、それほど多くはありませんでした。

まさにここにゴルフをしようが、それは単一交互に行うことができるわけではありません
#!/usr/bin/perl 

use strict; 

my @array = (
    "CategoryA--", 
    "5: UserA", 
    "6: UserB", 
    "7: UserC", 
    "CategoryB--", 
    "4: UserA", 
    "5: UserB" 
); 

my ($dataFileContents, $currentCategory); 

for (@array) { 
    $currentCategory = $1 if (/(Category[A-Z])--/); 
    if (/(\d+): (User[A-Z])/) { 
     $dataFileContents->{$2}->{$currentCategory} = $1 
    } 

} 
+0

TESTの場合、私の$ blah; Perl 5.12では廃止予定です。私は信じて、常に落胆しています。状態変数(Perl 5.10)を使用するか、周囲のスコープ(以前のバージョンのPerl)で変数を宣言してください。 –

+0

\ dは、Perl 5.8と5.10では[0-9]と一致しません。数字属性( "\ x {1815}"や "\ x {FF15}"など)を持つUNICODE文字と一致します。[0-9]を意味する場合は、[0-9]を使用するか、バイトプラグマを使用する必要があります(ただし、すべての文字列を1バイト文字に変換します)。 –

+0

__DATA__トークンを使用すると(Chas。didのように)、この種のテストは簡単になり、読みやすくなります。 –

1

my (%data, $category); 
while (<DATA>) { 
    next unless /^(?:(Category\w+)|(\d+):\s*(User\w+))/; 
    ($1 ? $category = $1 : 0) or $data{$3}{$category} = $2;  
} 

Data::Dumper(実際Smart::Comments)は出力を示しています。

{ 
    UserA => { 
      CategoryA => '5', 
      CategoryB => '4' 
      }, 
    UserB => { 
      CategoryA => '6', 
      CategoryB => '5' 
      }, 
    UserC => { 
      CategoryA => '7' 
      } 
}  
0
#!/usr/bin/perl 

use strict; 
use Data::Dumper; 

print "Content-type: text/html\n\n"; 

my ($x,%data); 
do { 
    if (/^(Category\w+)/) { 
     $x=$1; 
    } elsif (/^([0-9]+):\s*(User\w)/) { 
     if (!defined($data{$2})) { 
      $data{$2} = {$x,int($1)}; 
     } else { 
      $data{$2}{$x} = int($1); 
     } 
    } 
} while (<DATA>); 

print Dumper \%data; 


__DATA__ 
CategoryA-- 
5: UserA 
6: UserB 
7: UserC 
CategoryB-- 
4: UserA 
5: UserB 

RESULT :

$VAR1 = { 
    'UserC' => { 
     'CategoryA' => 7 
       }, 
    'UserA' => { 
     'CategoryA' => 5, 
     'CategoryB' => 4 
       }, 
    'UserB' => { 
     'CategoryA' => 6, 
     'CategoryB' => 5 
    } 
}; 
関連する問題