更换开始和结束字符串,同时保持封闭值?

时间:2017-06-11 20:12:57

标签: java regex

String value="==Hello==";

对于上面的字符串,我必须将“==”标记替换为<Heading>Hello</Heading>。我试过这样做:

value = value.replaceAll("(?s)\\=\\=.","<heading>");
value = value.replaceAll(".\\=\\=(?s)","</heading>");

然而,我的原始数据集非常庞大,需要更换许多像这样的字符串。以上是否可以在一个声明中执行,优先考虑性能?

正则表达式不应该影响表单的字符串===<value>===,其中value是任何字符串[a-z,A-Z]。

2 个答案:

答案 0 :(得分:0)

试试这个:

public static void main(final String[] args) {
        String value = "===Hello===";
        value = value.replaceAll("===([^=]+)===", "<Heading>$1</Heading>");
        System.out.println(value);
    }

答案 1 :(得分:0)

为避免多次迭代字符串以首先替换==def==然后Matehr#appendReplacement,我们可以迭代一次,感谢Matcher#appendTail=动态决定如何替换找到匹配项(基于(={2,3})([a-z]+)\1的数量)。

可以搜索的正则表达式找到两个描述的案例可能看起来像(?<name>subregex)但是为了使它更有用,我们可以使用named groups [a-z]而不是[^=]+使用更一般的Pattern p = Pattern.compile("(?<eqAmount>={2,3})(?<value>[^=]*)\\k<eqAmount>");

这会给我们

eqAmount

名为==的群组将保留===\\k<eqAmount>==是对该群组的反向引用,这意味着正则表达式希望找到它===eqAmount,具体取决于==已经拥有的内容。

现在我们需要在===Map<String,String> replacements = new HashMap<>(); replacements.put("===", "<subheading>${value}</subheading>"); replacements.put("==", "<heading>${value}</heading>"); 和替换之间进行一些映射。要保持这种映射,我们可以使用

${value}

value是指捕获名为(?<value>[^=]*)的群组 - 此处为==,因此它会在===String input = "===foo=== ==bar== ==baz== ===bam==="; Map<String, String> replacements = new HashMap<>(); replacements.put("===", "<subheading>${value}</subheading>"); replacements.put("==", "<heading>${value}</heading>"); Pattern p = Pattern.compile("(?<eqAmount>={2,3})(?<value>[^=]*)\\k<eqAmount>"); StringBuffer sb = new StringBuffer(); Matcher m = p.matcher(input); while (m.find()) { m.appendReplacement(sb, replacements.get(m.group("eqAmount"))); } m.appendTail(sb); String result = sb.toString(); System.out.println(result); 之间保留文字。

现在让我们看看它是如何工作的:

<subheading>foo</subheading> <heading>bar</heading> <heading>baz</heading> <subheading>bam</subheading>

输出:post_max_size = 24M upload_max_filesize = 20M