没有匹配组偏移操作的Java Regex组替换

时间:2014-10-29 18:54:51

标签: java regex

对于非常特定类型的子序列,我经常面临从XHTML文档中删除<p></p>标记等要求。 (一个不允许使用String.replaceAll())。通常它的模式<p>${randomTextAndHTMLorJavascript}</p>但是一个常量是它总是一个带有大量垃圾的任意标签,后面跟着它的结束标签。没有标签嵌套!

我的问题是,除了手动操作Matcher对象之外,是否有人知道更高级别的抽象。在过去,我做过这些替换:

  1. 将问题作为数组副本处理,我在其中使用StringBuilder对象并使用Matcher.start(int)Matcher.end(int)方法来复制目标组。输入String。这有效,但感觉就像C,而不是Java。

  2. 执行循环,我使用开始标记查找第一个标记,并将match1.group()的结果作为第二个Matcher的输入来捕获结束标记,然后使用{ {1}}来处理输入字符串本身的替换。这有一个缺点,需要调用Matcher.replaceFirst()强制重新分析。 (我只将它用于一次性脚本或者如果输入集保证很小的话。)

  3. Matcher.reset()在一个代码上,替换它,除非与String.split()匹配,并使用match1重新构建字符串。针对表示结束标记序列的标记运行第二个StringBuilder,并在追加之前执行Matcher

  4. 我也尝试过使用String.replaceAll()方法,但对于像Java这样的语言来说仍然感觉太低了。

  5. 理想的是这样的方法签名:

    StringBuilder.deleteCharAt()

    最终,我希望在Java中替换正则表达式匹配组,而无需使用组/数组偏移。

1 个答案:

答案 0 :(得分:1)

对于XHTML(或其他XML)文档,一个(更多)更高级别的抽象将是XSL转换。它们比正则表达式更具表现力和强大功能,即使你具有内部结构来应对它们也能发挥作用。

或者如果你想让逻辑更接近Java,那么为什么不在替换字符串中使用反向引用:

Pattern pat = Pattern.compile("(<p>keep )(stuff I don't want)( this</p>)");
Matcher m = p.matcher(input);

// Replace matches to the pattern with the same thing less "stuff I don't want":
String output = m.replaceAll("$1$3");

我知道你说你不能使用replaceAll(),但我不清楚为什么你不能通过这个完成你在(1)中所描述的内容(例如)方法

当然,反向引用也适用于Matcher.replaceFirst()String.replaceAll()String.replaceFirst()

已编辑添加:

如果你想迭代地逐步完成,在匹配过程中做更多的事情,那么你应该研究Matcher.appendReplacement()(你也可以使用反向引用)和Matcher.appendTail()。< / p>