2010-09-30 105 views
1

我有一個字符串模板,我需要從中獲取#elseif塊的列表。正則表達式 - 需要幫助

但它只返回一個匹配,即第一個#elseif塊,而不是第二個。我還需要獲得第二個#elseif塊。你能幫我做到嗎?請找到下面的字符串模板。

String template = 
     "This is a sample document." 
      + "#abc (#processing)" 
      + "FIRST This text can be repeated many times until do while is called." 
      + "#abcif (v2)" 
      + "Some sample text after 1st ElseIf." 
      + "#abcif(v2)" 
      + "; 
+0

可能重複[正則表達式需要幫助。(http://stackoverflow.com/questions/3823362/regex-help-needed) – NullUserException 2010-09-30 04:01:21

+0

以前的職位是隻返回一個匹配。我需要得到所有elseif塊 – Apps 2010-09-30 04:05:27

+0

我認真的不認爲正則表達式是正確的解析工具。創建一個語法並使用ANTLR。 – 2010-09-30 04:44:16

回答

2

此代碼

Pattern regexp = Pattern.compile("#elseif\\b(.*?)(?=#(elseif|else|endif))"); 
Matcher matcher = regexp.matcher(template); 
while (matcher.find()) 
    System.out.println(matcher.group()); 

會產生

#elseif ($variable2)Some sample text after 1st ElseIf. 
#elseif($variable2)This text can be repeated many times until do while is called. SECOND ELSEIF 
#elseif ($variable2)SECOND Some sample text after 1st ElseIf. 
#elseif($variable2)SECOND This text can be repeated many times until do while is called. SECOND ELSEIF 

祕密在於positive lookahead(?=#(elseif|else|endif)),因此#elseif,#else#endif將被匹配,但字符不被消耗。這樣他們可以在下一次迭代中找到。的

1
#elseif\b(?:(?!#else\b|#endif\b).)* 

將在塊匹配所有從第一#elseif直到(但不包括)最近#else#endif

Pattern regex = Pattern.compile("#elseif\\b(?:(?!#else\\b|#endif\\b).)*", Pattern.DOTALL); 
Matcher regexMatcher = regex.matcher(subjectString); 
while (regexMatcher.find()) { 
    // matched text: regexMatcher.group() 
    // match start: regexMatcher.start() 
    // match end: regexMatcher.end() 
} 

然後,如果您需要在那場比賽中提取單個'#elseif`塊,從上面的第一個正則表達式匹配的效果,請使用

#elseif\b(?:(?!#elseif\b).)* 

。在Java:

Pattern regex = Pattern.compile("#elseif\\b(?:(?!#elseif\\b).)*", Pattern.DOTALL); 

1

這裏的大問題是,你需要#elseif(..)既作爲開始,並在您的正則表達式停止標記。第一場比賽是子

#elseif ($variable2)Some sample text after 1st ElseIf.#elseif($variable2) 

,然後它開始該序列後,尋找下一個比賽。所以它會從第一個#if表達式中錯過第二個#elseif,因爲#elseif($variable2)序列已經是前一場比賽的一部分。

我會盡量拆分上的圖案"\\#elseif\\s*\\((.*?)\\)"字符串:

String[] temp = template.split("\\#elseif\\s*\\((.*?)\\)"); 

從現在開始temp[1]所有臨時條目在它們開始的#elseif塊。在(?:#else|#endif)另一個分裂應該給你包含什麼,但明文字符串:

for (String s:temp) 
    System.out.println(s.split("(?:#else|#endif)")[0]); 

(無法測試第二分裂,如果它不工作,把它作爲唯一的戰略的意見; ))

1
private static final Pattern REGEX = Pattern.compile(
    "#elseif\\s*\\(([^()]*)\\)(.*?)(?=#elseif|#else|#endif)"); 

public static void main(String[] args) { 
    Matcher matcher = REGEX.matcher(template); 
    while (matcher.find()) { 
     System.out.println(matcher.group(2)); 
    } 
}