3

区切り文字を含むことができるいくつかの保護された値と区切られた値を一致させるための正規表現が必要です。

例えば:

"A,B,{C,D,E},F"

与えるでしょう:

  • 「あ」
  • "B"
  • "{C,D,E}"
  • 「フ」

次のように、保護された値をネストできることに注意してください。

"A,B,{C,D,{E,F}},G"

与えるでしょう:

  • 「あ」
  • "B"
  • "{C,D,{E,F}}"
  • 「グ」

次のように、文字の反復を使用してその機能を既にコーディングしています。

sub Parse
{
  my @item;

  my $curly;
  my $string;
  foreach(split //)
  {
    $_ eq "{" and ++$curly;
    $_ eq "}" and --$curly;

    if(!$curly && /[,:]/)
    {
      push @item, $string;
      undef $string;
      next;
    }
    $string .= $_;
  }

  push @item, $string;
  return @item;
}

しかし、正規表現を使用すると、間違いなくはるかに優れたものになります。

4

6 に答える 6

2

ネストをサポートする正規表現は次のようになります。

my @items;
push @items, $1 while
   /
      (?: ^ | \G , )
      (
         (?: [^,{}]+
         |   (
                \{
                   (?: [^{}]
                   |   (?2)
                   )*
                \}
             )
         |   # Empty
         )
      )
   /xg;

$ perl -E'$_ = shift; ... say for @items;' 'A,B,{C,D,{E,F}},G'
A
B
{C,D,{E,F}}
G

抽出と検証を同時に行うことはできないため、有効な入力を前提としています。(まあ、物事を本当に面倒にすることなくではありません。)

于 2012-07-27T18:35:19.523 に答える
1

nhahtdhの回答から改善されました。

$_ = "A,B,{C,D,E},F";
while ( m/(\{.*?\}|((?<=^)|(?<=,)).(?=,|$))/g ) {
    print "[$&]\n";
}

再度改善しました。これを見てください!

$_ = "A,B,{C,D,{E,F}},G";
while ( m/(\{.*\}|((?<=^)|(?<=,)).(?=,|$))/g ) {
    print "$&\n";
}

それは得ます:

A
B
{C,D,{E,F}}
G
于 2012-07-27T10:28:57.257 に答える
1
$a = "A,B,{C,D,E},F";
while ($a =~ s/(\{[\{\}\w,]+\}|\w)//) {
    push (@res, $1);
}
print "\@res: @res\n"

結果:

@res: A B {C,D,E} F

\{[\{\}\w,]+\}説明 : 保護されたブロックまたは 1 つの文字のみをループ内で連続して一致させようとし、一致する\w場合は元の文字列から削除します。一致するたびに、それ (つまり$1) を配列に保存します。

于 2012-07-27T07:24:24.183 に答える
0

この正規表現を試してください。正規表現を使用して、トークンを照合および抽出します。

/(\{.*?\}|(?<=,|^).*?(?=,|$))/

私はこのコードをPerlでテストしていません。

ここでは、正規表現エンジンがどのように機能するかについての仮定があります(\{.*?\}2番目の部分の前に最初の部分を一致させようとすると思います)。また、入れ子になった中かっこと、および不適切にペアになっている中かっこはないと思います。

于 2012-07-27T07:25:08.227 に答える
0

これは bash の正規表現です。

chronos@localhost / $ echo "A,B,{C,D,E},F" | grep -oE "(\{[^\}]*\}|[A-Z])"
A
B
{C,D,E}
F
于 2012-07-27T07:23:55.900 に答える
-2
$s = "A,B,{C,D,E},F";
@t = split /,(?=.*{)|,(?!.*})/, $s;
于 2012-07-27T07:59:25.663 に答える