2011-12-12 23 views
5

I次の文字列があります:私は/,/ことによってそれを分割するのではなく、のみ場合はその内部ブラケットは、例えば、この場合には、結果があるべきではないしようとしているPerlの分割と正規表現

'100% California Grown Olives, Water, Salt And Ferrous Gluconate (An,Iron, Derivative),asasd, sadasda' 

を:

100% California Grown Olives 
Water 
Salt And Ferrous Gluconate (An,Iron, Derivative) 
asasd 
sadasda 

おかげで、

+1

ネストされたかっこの可能性はありますか?その場合、正規表現は法案に適合しない可能性があります。 –

+1

いいえ、できません。一組のかっこ、または二重ではあるが入れ子になっていない – snoofkin

答えて

11
@result = split(m/,(?![^()]*\))/, $subject); 

T次の括弧(もしあれば)が閉じ括弧でない場合にのみ、コンマで区切ります。 Jack Maneyが正しく述べたように、ネストされたカッコが発生すると、これが失敗する可能性があります。

説明:

,  # Match a comma. 
(?!  # Assert that it's impossible to match... 
[^()]* # any number of non-parenthesis characters 
\)  # followed by a closing parenthesis 
)  # End of lookahead assertion 
1

まずあなたが括弧を構成するものを決定する必要があり、彼らはネストすることができます。 (この答えのために、私は彼らができると仮定します)。そして、あなたはテキストからこれらの括弧ブロックを削除し、プレースホルダと交換する必要があります。

my @parens; 
$str =~ s/(\((?: (?0)|[^()])* \))/push @parens, $1; "PARENS_$#parens"/gex; 

は、だから今は、のようなものが残されています。

'100% California Grown Olives, Water, Salt And Ferrous Gluconate PAREN_0,asasd, 
sadasdas.' 

そして、それを分割することになりました簡単ですそれはカンマで。次に、分割された各部分で、PAREN_\d+トークンをスキャンし、@parens配列のものと置き換えます。ソースコンテンツに応じて、より一意のプレースホルダ名を使用する必要があります。

ような何か:

s/PARENS_(\d+)/$parens[$1]/ge for my @segs = split /,\s*/ => $str; 

say for @segs; 

例えば、文字列の:

my $str = "foo (b,a,r), baz (foo, (bar), baz), biz"; 

プリント:

foo (b,a,r) 
baz (foo, (bar), baz) 
biz 
+0

'$ parens [$ 1]'を評価する必要はないと思う。 – TLP

0

あなたはそれが簡単にあなたがしたい何のための正規表現を構築するために見つけるかもしれませんあなたが削除したいものではなく、マッチします。 (これは一致の数を制限したくないと仮定しています)。