2010-09-30 140 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)); 
    } 
}