[英]Using RegEx to balance match parenthesis
我正在嘗試創建一個 .NET RegEx 表達式,它將正確平衡我的括號。 我有以下正則表達式:
func([a-zA-Z_][a-zA-Z0-9_]*)\(.*\)
我試圖匹配的字符串是這樣的:
"test -> funcPow((3),2) * (9+1)"
應該發生的是 Regex 應該匹配從funcPow
到第二個funcPow
括號的所有內容。 它應該在第二個右括號之后停止。 相反,它一直匹配到最后一個右括號。 正則表達式返回這個:
"funcPow((3),2) * (9+1)"
它應該返回這個:
"funcPow((3),2)"
對此的任何幫助將不勝感激。
正則表達式絕對可以做平衡括號匹配。 它可能很棘手,並且需要一些更高級的 Regex 功能,但這並不太難。
例子:
var r = new Regex(@"
func([a-zA-Z_][a-zA-Z0-9_]*) # The func name
\( # First '('
(?:
[^()] # Match all non-braces
|
(?<open> \( ) # Match '(', and capture into 'open'
|
(?<-open> \) ) # Match ')', and delete the 'open' capture
)+
(?(open)(?!)) # Fails if 'open' stack isn't empty!
\) # Last ')'
", RegexOptions.IgnorePatternWhitespace);
平衡匹配組有幾個功能,但在這個例子中,我們只使用捕獲刪除功能。 行(?<-open> \\) )
將匹配 a )
並刪除之前的“打開”捕獲。
最棘手的一行是(?(open)(?!))
,讓我解釋一下。 (?(open)
是一個條件表達式,只有比賽,如果有一個“開放”的拍攝。 (?!)
為負表達總是失敗。因此, (?(open)(?!))
說:“如果有一個開放的捕獲,然后失敗”。
微軟的文檔也很有幫助。
使用平衡組,它是:
Regex rx = new Regex(@"func([a-zA-Z_][a-zA-Z0-9_]*)\(((?<BR>\()|(?<-BR>\))|[^()]*)+\)");
var match = rx.Match("funcPow((3),2) * (9+1)");
var str = match.Value; // funcPow((3),2)
(?<BR>\\()|(?<-BR>\\))
是一個平衡組(我用於名稱的BR
用於Brackets
)。 這樣就更清楚了(?<BR>
\\( )|(?<-BR>
\\) )
也許,以便\\(
和\\)
更加“明顯”。
如果你真的很討厭自己(和世界/你的合作程序員)使用這些東西,我建議使用RegexOptions.IgnorePatternWhitespace
和“噴灑”空格無處不在:-)
正則表達式僅適用於正則語言。 這意味着正則表達式可以找到“a's 和 b's 的任意組合”之類的東西。( ab
或babbabaaa
等)但他們找不到“ n a's, one b, n a's”。( a^nba^n
) 正則表達式不能保證第一組 a 匹配第二組 a。
因此,它們無法匹配相同數量的左括號和右括號。 編寫一個一次遍歷字符串一個字符的函數是很容易的。 有兩個計數器,一個用於打開paren,一個用於關閉。 在遍歷字符串時增加指針,如果opening_paren_count != closing_parent_count
返回 false。
func[a-zA-Z0-9_]*\((([^()])|(\([^()]*\)))*\)
您可以使用它,但如果您使用 .NET,可能會有更好的選擇。
這部分你已經知道了:
func[a-zA-Z0-9_]*\( --weird part-- \)
--weird part-- 部分只是意味着; (
允許任何字符.
或|
任何部分(.*)
存在任意多次)*
。 唯一的問題是,你不能匹配任何字符.
,您必須使用[^()]
來排除括號。
(([^()])|(\([^()]*\)))*
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.