2015-07-10 55 views
2

考慮下面的字符串中註釋掉逗號:拆分成字由未中匹配括號

blah, foo(a,b), bar(c,d), yo 

我想提取字符串列表:

blah 
foo(a,b) 
bar(c,d) 
yo 

在我看來,我應該能夠在這裏使用引號,但我正在努力與正則表達式。有人可以幫我嗎?

+0

我補充說,處理嵌套括號的解決方案。不過,它可能比@ stribizhev的速度慢,所以如果你不需要處理這個問題,就使用它們。 – Lynn

+3

另外,瘋狂猜測,但對於你寫的字符串,你可以簡單地分割','(注意空間)。內部「參數」不包含空格。如果你的意見也是這樣,那麼你也可以這樣做。 – Lynn

回答

3

Perl有一個小東西regex recursion,所以你也許可以找:

  • 無論是裸字狀含blah沒有括號(\w+

  • 「呼叫」,如\w+\((?R)(, *(?R))*\)

總的正則表達式是(\w+(\((?R)(, ?(?R))*\))?),其中seems to work

+1

我會說更好更清潔的方式 – vks

1

您可以使用下面的正則表達式中拆分使用:

\([^()]*\)(*SKIP)(*F)|\s*,\s* 

隨着\([^()]*\),我們匹配(跟着比()其他0個或更多字符,然後接着用)。如果找到了括號內的結構,我們就會與(*SKIP)(*F)匹配失敗,然後我們只能匹配包含可選空格的逗號。

demo

#!/usr/bin/perl 
my $string= "blah, foo(a,b), bar(c,d), yo"; 
my @string = split /\([^()]*\)(*SKIP)(*F)|\s*,\s*/, $string; 

foreach(@string) { 
    print "$_\n"; 
} 

爲了解釋嵌套的括號內的逗號,你可以使用

my @string = split /\((?>[^()]|(?R))*\)(*SKIP)(*F)|\s*,\s*/, $string; 

這裏是一個IDEONE demo

隨着\((?>[^()]|(?R))*\)我們匹配所有平衡() S和失敗如果在動詞(*SKIP)(*F)中找到匹配項,然後我們將逗號與o空白周圍(以便稍後不手動修剪字符串)。

對於blah, foo(b, (a,b)), bar(c,d), yo字符串,其結果是:

blah 
foo(b, (a,b)) 
bar(c,d) 
yo 
+1

這不處理'blah,foo(a,bar(b,c)),yo',但我不確定OP是否需要它。 – Lynn

+0

@Mauris:這很容易解決,因爲你看到。 –

+0

@stribizhev你的修復沒有做任何改變似乎https://regex101.com/r/hR7tH4/8 – vks

1

有一個solution給出鮑羅丁爲您的question(這是類似於這個問題)。正則表達式的一個小小的改變會給你想要的輸出:(這不會對嵌套的括號工作)

use strict; 
use warnings; 
use 5.010; 

my $line = q<blah, foo(a,b), bar(c,d), yo>; 

my @words = $line =~/(?: \([^)]*\) | [^,])+ /xg; 

say for @words; 

輸出:

blah 
foo(a,b) 
bar(c,d) 
yo