2013-01-18 54 views
0

我試圖用正則表達式解析<tag>=<value>類型的字符串,但遇到了一些問題,增加了對引用值的支持。我們的想法是,任何帶引號的值應修剪的前/後的空白,使[ Hello ]成爲[Hello](請忽略的方括號。)使用正則表達式提取帶引號和不帶引號的值

然而,當值是引用,我想要的東西直至幷包括雙行情被刪除,但沒有進一步的,所以[ " Hello World " ]將成爲[" Hello World "]

到目前爲止,我已經拿出來與這一模式匹配(注意,有些字符已經越獄或逃脫雙重避免以下代碼它們被解釋爲三圖或其他C格式字符)。

void getTagVal(const std::string& tagVal) 
{ 
    boost::smatch what; 
    static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\a-zA-Z0-9 /\\._]+?)\"\?\?\\s*$"); 

    if (boost::regex_match(tagVal, what, pp)) 
    { 
     const string tag = static_cast<const string&>(what[1]); 
     const string val = static_cast<const string&>(what[2]); 

     cout << "Tag = [" << tag << "] Val = [" << val << "]" << endl; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    getTagVal("Qs1= \" Hello World \" "); 
    getTagVal("Qs2=\" Hello World \" "); 
    getTagVal("Qs3= \" Hello World \""); 
    getTagVal("Qs4=\" Hello World \""); 
    getTagVal("Qs5=\"Hello World \""); 
    getTagVal("Qs6=\" Hello World\""); 
    getTagVal("Qs7=\"Hello World\""); 

    return 0; 
} 

取出雙重轉義,這個分解爲:

  • ^ - 線的開始。
  • \s* - 可選數量的空白。
  • ([a-zA-Z0-9_-]+) - 一個或多個字母數字或短劃線或下劃線。這被作爲標籤捕獲。
  • \s* - 可選數量的空白。
  • = - 一個「相等」的符號。
  • \s* - 可選數量的空白。
  • "?? - 可選的雙引號(非貪婪)。
  • ([%:\a-zA-Z0-9 /\._]+?) - 一個或多個字母數字或空格,下劃線,百分比,冒號,句點,前進或後退斜槓。這被捕獲爲值(非貪婪)。
  • "?? - 可選的雙引號(非貪婪)。
  • \s* - 可選數量的空白。
  • $ - 線

的結束對於例如調用main(),我希望得到:

Tag = [Qs1] Val = [ Hello World ] 
Tag = [Qs2] Val = [ Hello World ] 
Tag = [Qs3] Val = [ Hello World ] 
Tag = [Qs4] Val = [ Hello World ] 
Tag = [Qs5] Val = [Hello World ] 
Tag = [Qs6] Val = [ Hello World] 
Tag = [Qs7] Val = [Hello World] 

但我實際得到的是:

Tag = [Qs1] Val = [" Hello World ] 
Tag = [Qs2] Val = [" Hello World ] 
Tag = [Qs3] Val = [" Hello World ] 
Tag = [Qs4] Val = [" Hello World ] 
Tag = [Qs5] Val = ["Hello World ] 
Tag = [Qs6] Val = [" Hello World] 
Tag = [Qs7] Val = ["Hello World] 

所以這幾乎是正確的,但由於某種原因,即使我特別將r的值部分括起來,第一個引號仍在輸出值中egex與外面的報價。

+0

我們展示的代碼,你正在使用的文本匹配 – Anirudha

+0

@ Some1.Kill.The.DJ:現在應該在那裏。 –

回答

1

我會改變部分開始與第一次報價,以替代:

"([^"]+)"|([%:\a-zA-Z0-9 /\._]+)\s* 

然後,您將不得不處理的兩種可能性或不使用引號的文本在結束了在第二或第三捕獲括號對正則表達式的主機代碼。

+0

@FrankPi:謝謝。不過,我想我明白了。 –

0

找出問題所在。

當使用\你,因爲這是C字符串內處理,因此需要在那裏躲過要小心,但它也將被正則表達式引擎,因此,如果你不小心處理\\a變得\a這是絕對不是你想要的。

因此,要告訴它我想要一個\在我的字符集中(這是我的諷刺做法,它們被用作格式字符串中的轉義序列),那麼您必須雙重轉義他們這麼

static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\a-zA-Z0-9 /\\._]+?)\"\?\?\\s*$"); 

變爲:

static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\\\a-zA-Z0-9 /._]+?)\"\?\?\\s*$"); 

(即你需要使它\\\\

相關問題