【问题标题】:Regular Expression- Help needed正则表达式 - 需要帮助
【发布时间】:2010-09-30 03:58:36
【问题描述】:

我有一个字符串模板,我需要从中获取#elseif 块的列表。例如,第一个 #elseif 块将来自

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

,第二个#elseif块来自#elseif($variable2)This text can be repeated many times until do while is called. SECOND ELSEIF

等等。我为此使用了以下正则表达式。

String regexElseIf="\\#elseif\\s*\\((.*?)\\)(.*?)(?:#elseif|#else|#endif)"; 

但它只返回一个匹配项,即第一个#elseif 块而不是第二个。我还需要获得第二个#elseif 块。你能帮我这样做吗?请找到以下字符串模板。

  String template =
        "This is a sample document."
            + "#if ( $variable1 )"
            + "FIRST This text can be repeated many times until do while is called."
            + "#elseif ( $variable2 )"
            + "Some sample text after 1st ElseIf."
            + "#elseif($variable2)"
            + "This text can be repeated many times until do while is called. SECOND ELSEIF"
            + "#else "
            + "sample else condition  "
            + "#endif "
            + "Some sample text."
            + "This is the second sample document."
            + "#if ( $variable1 )"
            + "SECOND FIRST This text can be repeated many times until do while is called."
            + "#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"
            + "#else " + "SECOND sample else condition  " + "#endif "
            + "SECOND Some sample text.";

【问题讨论】:

  • Regex Help needed. 的可能重复项
  • 上一篇文章只返回一个匹配项。我需要获取所有 elseif 块
  • 我真的不认为正则表达式是这样的解析工具。创建语法并使用 ANTLR。

标签: java regex pattern-matching


【解决方案1】:

这段代码

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会被匹配,但字符不会被消耗。这样下一次迭代就可以找到它们。

【讨论】:

    【解决方案2】:
    #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);
    

    等等

    【讨论】:

      【解决方案3】:

      这里最大的问题是您需要#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]);
      

      (无法测试第二次拆分,如果它不起作用,则仅将其视为策略上的建议;))

      【讨论】:

        【解决方案4】:
        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));
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-11-30
          • 2023-03-19
          • 2021-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-01
          • 2016-02-01
          相关资源
          最近更新 更多