簡體   English   中英

C ++:使用簡單的正則表達式解析還是應該使用sscanf?

[英]C++: parsing with simple regular expression or shoud I use sscanf?

我需要解析一個像func1(arg1, arg2); func2(arg3, arg4);這樣的字符串func1(arg1, arg2); func2(arg3, arg4); func1(arg1, arg2); func2(arg3, arg4); 這不是一個非常復雜的解析問題,所以我寧願避免訴諸於flex / bison或類似的實用程序。

我的第一個方法是嘗試使用POSIX C regcomp/regexec或C ++ std::regex Boost實現。 我編寫了以下正則表達式,該表達式不起作用(我將繼續解釋為什么)。

 "^"
 "[ ;\t\n]*"
 "(" // (1) identifier
    "[a-zA-Z_][a-zA-Z0-9_]*"
 ")"
 "[ \t\n]*"
 "(" // (2) non-marking
    "\["
    "(" // (3) non-marking
       "[ \t]*"
       "(" // (4..n-1) argument
          "[a-zA-Z0-9_]+"
       ")"
       "[ \t\n]*"
       ","
    ")*"
    "[ \t\n]*"
    "(" // (n) last argument
       "[a-zA-Z0-9_]+"
    ")"
    "]"
 ")?"
 "[ \t\n]*"
 ";"

請注意,組1捕獲標識符,而組4..n-1旨在捕獲除最后一個參數以外的參數,后者由組n捕獲。

當我將此正則表達式應用於例如func(arg1, arg2, arg3) ,得到的結果是數組{func, arg2, arg3} 這是錯誤的,因為arg1不在其中!

問題在於,在標准正則表達式庫中,子標記僅捕獲最后一個匹配項。 換句話說,例如,如果對"babb"應用了正則表達式"((a*|b*))*" ,則內部匹配的結果將為bb並且所有先前的捕獲都將被遺忘。

令我煩惱的另一件事是,在發生錯誤的情況下,無法知道哪個字符未被識別,因為當輸入被拒絕時,這些函數提供的解析器狀態信息很少。

所以我不知道我是否在這里遺漏了一些東西...在這種情況下,我應該使用sscanf或類似的東西嗎?

請注意,我更喜歡使用C / C ++標准庫(甚至可以使用boost)。

如何增強精神

如果要使用Regex,將其分為2個步驟會更簡單。 在步驟1中,您發現

func1(stuff);

並將其轉換為func1和其他stuff

在下一步中,您分析“東西”以找到該函數的所有單獨的參數。

如果這是Ruby,我將從匹配開始

%r{
   ([a-zA-Z_][a-zA-Z0-9_]*)   #identifier
   \s*                        #whitespace after the identifier
   \(                         #open paren
     ([^)]*)                  #all arguments as one string
   \)                         #close paren
}x

然后,我將使用$2.split(/\\s*,\\s*/)將這些分段分開。 我認為C ++標准庫中沒有等效於split的內容,但是我認為boost :: regex_split可以做到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM