2012-07-27 38 views
3

我想要一個正則表達式來匹配分隔值和一些可以包含分隔符的受保護值。正則表達式匹配受保護的分隔值

例如:

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

會給:

  • 「A」
  • 「B」
  • 「{C,d,E}」
  • 「F」

懇求本身注意保護值可以嵌套,如下:

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

會給:

  • 「A」
  • 「B」
  • 「{C,d,{E,F }}」
  • 「G」

我已經編碼的功能與角色迭代如下:

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; 
} 

但是它肯定會對正則表達式更好。

+0

你有'{{A},{B}}'作爲輸入? – nhahtdh 2012-07-27 07:34:22

+0

是的,我可以嵌套'{}',例如'A,B,{D,{E,F},G},H'應該給'A''B'' {D,{E,F} ,G}''H' – Christophe 2012-07-27 07:53:30

+1

正則表達式不能處理任意級別的嵌套。您必須指定最大嵌套級別,或者使用適當的解析器。 – tripleee 2012-07-27 14:23:43

回答

1

從nhhtdh的回答中得到了改進。

$_ = "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 
+0

令人印象深刻的正則表達式:-D雖然依然不支持嵌套值 – Christophe 2012-07-27 13:55:50

+0

這是工作恭喜!這麼漂亮的正則表達式 – Christophe 2012-07-30 07:50:23

+0

但有一個問題,如果有兩個或更大括號出現與分離正常的字母,比如 「A,B,{C,d,{E,F}},G,{H,I},J」,此正則表達式將得到 甲 乙 {C ,d,{E,F}},G,{H,I} Ĵ 也許這不是你想要的。 – xiangpeis 2012-08-01 02:39:08

0

這裏是bash的正則表達式:

[email protected]/$ echo "A,B,{C,D,E},F" | grep -oE "(\{[^\}]*\}|[A-Z])" 
A 
B 
{C,D,E} 
F 
+0

我認爲他想用'perl'? – BaL 2012-07-27 07:24:52

+0

它應該在Perl中工作。這與你發佈的內容幾乎相同。 – theon 2012-07-27 07:32:31

+0

我同意,除了我會使用'\ w'而不是'[A-Z]',因爲它更通用。 :-) – BaL 2012-07-27 07:37:40

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,]+\}或只是一個單一的字符\w以連續匹配循環,如果匹配,則從原始字符串中刪除它。每當有一場比賽,我們將它存儲(意思是$1)在陣列中,等等!

+0

如果沒有嵌套的'{}' – Christophe 2012-07-27 07:50:09

0

試試這個正則表達式。使用正則表達式來匹配和提取令牌。

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

我還沒有在Perl中測試過這段代碼。

有一個關於正則表達式引擎如何工作的假設(我假設它會嘗試在第二部分之前匹配第一部分\{.*?\})。我也假定沒有嵌套的花括號,並且配對的花括號很差。

+0

看起來有點複雜,那很好用:-)然後你沒有測試它嗎? :-) – BaL 2012-07-27 07:26:25

+0

@BaL:只測試了ruby上的正則表達式。我不知道Perl足以爲它寫一個工作測試。這有點複雜,因爲我認爲A,B,C等代表一些真實的文本,而不是單個字符。 – nhahtdh 2012-07-27 07:29:07

-2
$s = "A,B,{C,D,E},F"; 
@t = split /,(?=.*{)|,(?!.*})/, $s; 
+2

不適用於嵌套'{}' – Christophe 2012-07-27 08:34:46

+0

那麼他爲什麼接受他的回答而不是我的? !!d加上他不給任何解釋:-( – BaL 2012-07-27 09:49:59

2

支持嵌套看起來如下:A正則表達式:

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 

假設,因爲它可以有效的輸入」 t在s處提取並驗證Ame時間。 (當然,不是沒有做的事情非常的混亂。)