在{{code}} {{/ code}}之外匹配{{html ...}}的正则表达式阻止

时间:2016-06-23 00:06:08

标签: java regex

我尝试在 Java 中编写正则表达式,以查找{{code}}块之外的所有{{html ...}}实例。我尝试了各种各样的表达方式,但它们似乎都太贪婪或太吝啬。

我一直在研究的样本字符串是:

{{code}}
  This is some plain text.
  {{html clean="false"}}
    This text is inside the html macro
  {{/html}}
{{/code}}
{{code}}
{{/code}}
blah
{{html clean="false2"}}
{{/html}}
{{html clean="false3"}}
{{code}}

我希望正则表达式匹配以下字符串:

1. {{html clean="false2"}}
2. {{html clean="false3"}}

我已经能够通过正则表达式匹配{{html ...}}的所有实例:

\{\{html.*?\}\}

返回

1. {{html clean="false"}}    <-- don't want to match this as its within {{code}} blocks
2. {{html clean="false2"}}
3. {{html clean="false3"}}

但是没有任何运气限制通过{{code}}块(使用正面和负面的前瞻/外观)。

非常感谢任何帮助,谢谢!

3 个答案:

答案 0 :(得分:2)

解决此问题的一种非常常见的方法是使用捕获组来区分匹配何时处于正确的上下文中。

考虑这个正则表达式:

\{\{code}}.*?\{\{/code}}|(\{\{html.*?}})

它将使正则表达式匹配{{code}}块,但是它将使该块内的任何内容在交替|(在捕获组中)的右侧保持匹配。 / p>

有关详细信息,请阅读The Best Regex Trick Ever(来自rexegg.com)。

String regex = "\\{\\{code}}.*?\\{\\{/code}}|(\\{\\{html.*?}})";
Matcher m = Pattern.compile(regex, Pattern.DOTALL).matcher(str);
List<String> matches = new ArrayList<>();
while (m.find()) {
    String match = m.group(1);
    if (match != null) {
        matches.add(match);
    }
}

Ideone Demo

答案 1 :(得分:1)

一个简单的解决方案,假设不存在荒谬的行数,例如设置一个boolean isInCode = false变量,然后使用for循环解析每一行,并在isInCode = true时设置{{code}}找到{1}}时找到isInCode = false{{/code}}找到{{html}}。然后,只要找到isInCode == false$(document).ready(function() { //Creating the show/hide function with jQuery Toggle $("#navToggle a").on ('click', function(event){ event.preventDefault(); $("header > nav").slideToggle("medium"); $("#logo").toggleClass("menuUp menuDown"); }); //Tidying up the Navigation Menu $(window).resize(function() { if($( window ).width() >= "767") { $("header > nav").css("display", "block"); $("header > nav > ul > li > a").siblings().removeAttr("style"); if($("#logo").attr('class') == "menuDown") { $("#logo").toggleClass("menuUp menuDown"); } } else { $("header > nav").css("display", "none"); //document.getElementById("categories").href = "categories/index.html"; } }); //Creating the Drop Down Menu for Mobile Devices $("header > nav > ul > li > a").click(function(e) { if($( window ).width() <= "767") { if($(this).siblings().size() > 0 ) { event.preventDefault(); $(this).siblings().slideToggle("fast") $(this).children(".toggle").html($(this).children(".toggle").html() == 'close' ? 'expand' : 'close'); } } }); }); ,就会知道您的条件得到满足

答案 2 :(得分:0)

在比赛结束后使用负面预测声明{{code}} [[/code}}之前出现(或两者都不出现):

(?s)\{\{html[^}]*\}\}(?=(.(?!\{\{/code\}\}))*(\{\{code\}\}|$))

一些测试代码:

String input =
        "{{code}}" +
        "This is some plain text." +
        "  {{html clean=\"false\"}}" +
        "    This text is inside the html macro" +
        "  {{/html}}" +
        "{{/code}}" +
        "{{code}}" +
        "{{/code}}" +
        "blah" +
        "{{html clean=\"false2\"}}" +
        "{{/html}}" +
        "{{html clean=\"false3\"}}" +
        "{{code}}";

Pattern p = Pattern.compile("(?s)\\{\\{html[^}]*\\}\\}(?=(.(?!\\{\\{/code\\}\\}))*(\\{\\{code\\}\\}|$))");
Matcher m = p.matcher(input);
while (m.find()) {
    System.out.println(m.group());
}

输出:

{{html clean="false2"}}
{{html clean="false3"}}