我正在将应用程序从PHP迁移到Java,并且在代码中大量使用正则表达式.我在PHP中遇到过似乎没有java等价物的东西:
preg_replace_callback()
对于正则表达式中的每个匹配,它调用一个函数,该函数将匹配文本作为参数传递.作为示例用法:
$articleText = preg_replace_callback("/\[thumb(\d+)\]/",'thumbReplace', $articleText); # ... function thumbReplace($matches) { global $photos; return ""; }
在Java中这样做的理想方法是什么?
当你可以在循环中使用appendReplacement()和appendTail()时,尝试模拟PHP的回调功能似乎是一项非常多的工作:
StringBuffer resultString = new StringBuffer(); Pattern regex = Pattern.compile("regex"); Matcher regexMatcher = regex.matcher(subjectString); while (regexMatcher.find()) { // You can vary the replacement text for each match on-the-fly regexMatcher.appendReplacement(resultString, "replacement"); } regexMatcher.appendTail(resultString);
重要提示:正如Kip在评论中所指出的,如果匹配的正则表达式在替换字符串上匹配,则此类具有无限循环错误.如果有必要的话,我会把它留给读者来修理它.
我不知道Java中内置的任何类似内容.使用Matcher类,你可以毫不费力地自己滚动:
import java.util.regex.*; public class CallbackMatcher { public static interface Callback { public String foundMatch(MatchResult matchResult); } private final Pattern pattern; public CallbackMatcher(String regex) { this.pattern = Pattern.compile(regex); } public String replaceMatches(String string, Callback callback) { final Matcher matcher = this.pattern.matcher(string); while(matcher.find()) { final MatchResult matchResult = matcher.toMatchResult(); final String replacement = callback.foundMatch(matchResult); string = string.substring(0, matchResult.start()) + replacement + string.substring(matchResult.end()); matcher.reset(string); } } }
然后打电话:
final CallbackMatcher.Callback callback = new CallbackMatcher.Callback() { public String foundMatch(MatchResult matchResult) { return ""; } }; final CallbackMatcher callbackMatcher = new CallbackMatcher("/\[thumb(\d+)\]/"); callbackMatcher.replaceMatches(articleText, callback);
请注意,您可以通过调用matchResults.group()
或获取整个匹配的字符串matchResults.group(0)
,因此不必将回调传递给当前字符串状态.
编辑:使它看起来更像PHP函数的确切功能.
这是原作,因为提问者喜欢它:
public class CallbackMatcher { public static interface Callback { public void foundMatch(MatchResult matchResult); } private final Pattern pattern; public CallbackMatcher(String regex) { this.pattern = Pattern.compile(regex); } public String findMatches(String string, Callback callback) { final Matcher matcher = this.pattern.matcher(string); while(matcher.find()) { callback.foundMatch(matcher.toMatchResult()); } } }
对于这个特定的用例,最好简单地对回调中的每个匹配进行排队,然后再向后运行它们.这将防止在修改字符串时重新映射索引.