Mik*_*ike 33 php java regex preg-replace
我正在将应用程序从PHP迁移到Java,并且在代码中大量使用正则表达式.我在PHP中遇到过似乎没有java等价物的东西:
preg_replace_callback()
Run Code Online (Sandbox Code Playgroud)
对于正则表达式中的每个匹配,它调用一个函数,该函数将匹配文本作为参数传递.作为示例用法:
$articleText = preg_replace_callback("/\[thumb(\d+)\]/",'thumbReplace', $articleText);
# ...
function thumbReplace($matches) {
global $photos;
return "<img src=\"thumbs/" . $photos[$matches[1]] . "\">";
}
Run Code Online (Sandbox Code Playgroud)
在Java中这样做的理想方法是什么?
Jan*_*rts 56
当你可以在循环中使用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);
Run Code Online (Sandbox Code Playgroud)
jdm*_*hal 22
重要提示:正如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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后打电话:
final CallbackMatcher.Callback callback = new CallbackMatcher.Callback() {
public String foundMatch(MatchResult matchResult)
{
return "<img src=\"thumbs/" + matchResults.group(1) + "\"/>";
}
};
final CallbackMatcher callbackMatcher = new CallbackMatcher("/\[thumb(\d+)\]/");
callbackMatcher.replaceMatches(articleText, callback);
Run Code Online (Sandbox Code Playgroud)
请注意,您可以通过调用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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个特定的用例,最好简单地对回调中的每个匹配进行排队,然后再向后运行它们.这将防止在修改字符串时重新映射索引.