0

Perlで解析しているデータがいくつかあり、近い将来、さまざまな形式のデータを追加する予定です。私がやりたいのは、文字列と正規表現を渡すことができる使いやすい関数を作成することです。これにより、括弧内に何でも返されます。これは次のように機能します(擬似コード):

sub parse {
  $data = shift;
  $regex = shift;

  $data =~ eval ("m/$regex/")
  foreach $x ($1...$n)
  {
    push (@ra, $x); 
  }
  return \@ra;
}

次に、私はそれを次のように呼ぶことができます:

@subs = parse ($data, '^"([0-9]+)",([^:]*):(\W+):([A-Z]{3}[0-9]{5}),ID=([0-9]+)');

ご覧のとおり、このコードにはいくつかの問題があります。evalが機能するかどうかはわかりませんが、「foreach」は間違いなく機能しません。また、括弧がいくつあるかを知らなければ、ループする回数もわかりません。

これは分割するには複雑すぎるので、私が見落としている別の機能や可能性がある場合は、私に知らせてください。

ご協力いただきありがとうございます!

4

4 に答える 4

6

リストコンテキストでは、正規表現は括弧で囲まれたすべての一致のリストを返します。

だからあなたがしなければならないのは:

my @matches = $string =~ /regex (with) (parens)/;

そして、それが一致したと仮定すると@matches、2つのキャプチャグループの配列になります。

したがって、正規表現を使用します。

my @subs = $data =~ /^"([0-9]+)",([^:]*):(\W+):([A-Z]{3}[0-9]{5}),ID=([0-9]+)/;

また、長い正規表現がある場合、Perlには、x正規表現の区切り文字を閉じる後の修飾子があります。修飾子を使用すると、x読みやすくするために正規表現内に空白と改行を入れることができます。

長さがゼロになる可能性のあるキャプチャグループが心配な場合は、一致をパススルーして@subs = grep {length} @subsそれらを除外できます。

于 2010-06-17T22:37:25.300 に答える
1

次に、次のように呼び出すことができます。

@subs = parse($data, 
          '^"([0-9]+)",([^:]*):(\W+):([A-Z]{3}[0-9]{5}),ID=([0-9]+)');

代わりに、次のように呼び出します。

parse($data, 
    qr/^"([0-9]+)",([^:]*):(\W+):([A-Z]{3}[0-9]{5}),ID=([0-9]+)/);

さらに、名前付きキャプチャ(つまり、Perl 5.10 以降)を使用できれば、作業はより簡単になります。次に例を示します。

#!/usr/bin/perl

use strict; use warnings;

my %re = (
    id => '(?<id> [0-9]+ )',
    name => '(?<name> \w+ )',
    value => '(?<value> [0-9]+ )',
);

my @this = (
    '123,one:12',
    '456,two:21',
);

my @that = (
    'one:[12],123',
    'two:[21],456',
);

my $this_re = qr/$re{id}   ,   $re{name}    : $re{value}/x;
my $that_re = qr/$re{name} : \[$re{value}\] , $re{id}   /x;

use YAML;

for my $d ( @this ) {
    print Dump [ parse($d, $this_re) ];
}

for my $d ( @that ) {
    print Dump [ parse($d, $that_re) ];
}

sub parse {
    my ($d, $re) = @_;
    return unless $d =~ $re;
    return my @result = @+{qw(id name value)};
}

出力:

---
- 123
- 1
- 12
---
- 456
- 2
- 21
---
- 123
- 1
- 12
---
- 456
- 2
- 21
于 2010-06-18T14:58:22.077 に答える
0

正規表現を使用して複雑な式を解析しようとしています。これは、このジョブには不十分なツールです。正規表現は上位の文法を解析できないことを思い出してください。直感的には、ネストされている可能性のある式を正規表現で解析することはできません。

于 2010-06-17T22:36:57.933 に答える
0

括弧のペア内のテキストを検索する場合は、Text::Balancedを使用します。

しかし、それはあなたがやりたいことではないので、役に立ちません。

于 2010-06-17T22:58:57.943 に答える