2013-05-31 40 views
1

我有一些文字,看起來像這樣:擊:需要在文本中找到匹配的括號(括號)內的文本

(something1)something2 

然而something1和something2也可能在他們裏面一些括號,如

(some(thing)1)something(2) 

我想提取something1(包括內部圓括號,如果有的話)給一個變量。既然我可以指望總是以開頭括號開頭的文本,我希望我能做一些事情,將第一個括號與正確的右括號相匹配,並提取中間。

到目前爲止我所嘗試過的一切都有可能匹配錯誤的結尾括號。

+3

這可證明是不可能找到匹配的括號使用正則表達式,所以一種方法就像逐個字符地搜索字符串,直到操作數n和右括號相等可能是最佳途徑 – Lorkenpeist

+0

謝謝,我發現你是正確的。 – Angelo

+1

@Angelo Perl正則表達式(嚴格來說,它們不是真正的正則表達式,因爲它們更強大)可以與括號匹配,並且受到'grep'(GNU'grep',至少)的支持。 – chepner

回答

1

由於這是顯然的東西是不可能的正則表達式,我已經使出皮卡人物1 1:

first="" 
count=0 
while test -n "$string" 
do 
    char=${string:0:1} # Get the first character 
    if [[ "$char" == ")" ]] 
    then 
     count=$(($count - 1)) 
    fi 
    if [[ $count > 0 ]] 
    then 
     first="$first$char" 
    fi 
    if [[ "$char" == "(" ]] 
    then 
     count=$(($count + 1)) 
    fi 
    string=${string:1} # Trim the first character 
    if [[ $count == 0 ]] 
    then 
     second="$string" 
     string="" 
    fi 
done 
2

您可以用Perl做到這一點:

echo "(some(thing)1)something(2)" | perl -ne '$_ =~ /(\((?:\(.*\)|[^(])*\))|\w+/s; print $1;' 
1

awk可以做到:

#!/bin/awk -f 
{ 
    for (i=1; i<=length; ++i) { 
     if (numLeft == 0 && substr($0, i, 1) == "(") { 
     leftPos = i 
     numLeft = 1 
     } else if (substr($0, i, 1) == "(") { 
     ++numLeft 
     } else if (substr($0, i, 1) == ")") { 
     ++numRight 
     } 
     if (numLeft && numLeft == numRight) { 
     print substr($0, leftPos, i-leftPos+1) 
     next 
     } 
    } 
} 

輸入:

(something1)something2 
(some(thing)1)something(2) 

輸出:

(something1) 
(some(thing)1) 
2

如果你有Perl的:

perl -MText::Balanced -nlE 'say [Text::Balanced::extract_bracketed($_, "()")]->[0]' <<EOF 
(something1)something2 
(some(thing)1)something(2) 
(some(t()()hing)()1)()something(2) 
EOF 

將打印

(something1) 
(some(thing)1) 
(some(t()()hing)()1) 
相關問題