Java 正则表达式替换为捕获组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1277157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Regex Replace with Capturing Group
提问by user
Is there any way to replace a regexp with modified content of capture group?
有没有办法用捕获组的修改内容替换正则表达式?
Example:
例子:
Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher(text);
resultString = regexMatcher.replaceAll(""); // *3 ??
And I'd like to replace all occurrence with $1 multiplied by 3.
我想用 $1 乘以 3 来替换所有出现的情况。
edit:
编辑:
Looks like, something's wrong :(
好像出了点问题:(
If I use
如果我使用
Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
String resultString = regexMatcher.replaceAll(regexMatcher.group(1));
} catch (Exception e) {
e.printStackTrace();
}
It throws an IllegalStateException: No match found
它抛出一个 IllegalStateException: No match found
But
但
Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
String resultString = regexMatcher.replaceAll("");
} catch (Exception e) {
e.printStackTrace();
}
works fine, but I can't change the $1 :(
工作正常,但我无法更改 $1 :(
edit:
编辑:
Now, it's working :)
现在,它正在工作:)
采纳答案by earl
How about:
怎么样:
if (regexMatcher.find()) {
resultString = regexMatcher.replaceAll(
String.valueOf(3 * Integer.parseInt(regexMatcher.group(1))));
}
To get the first match, use #find()
. After that, you can use #group(1)
to refer to this first match, and replace all matches by the first maches value multiplied by 3.
要获得第一场比赛,请使用#find()
. 之后,您可以使用#group(1)
引用此第一个匹配项,并将所有匹配项替换为第一个 maches 值乘以 3。
And in case you want to replace each match with that match's value multiplied by 3:
如果您想用该匹配的值乘以 3 替换每个匹配:
Pattern p = Pattern.compile("(\d{1,2})");
Matcher m = p.matcher("12 54 1 65");
StringBuffer s = new StringBuffer();
while (m.find())
m.appendReplacement(s, String.valueOf(3 * Integer.parseInt(m.group(1))));
System.out.println(s.toString());
You may want to look through Matcher
's documentation, where this and a lot more stuff is covered in detail.
您可能需要查看Matcher
的文档,其中详细介绍了这一点以及更多内容。
回答by Draemon
earl's answer gives you the solution, but I thought I'd add what the problem is that's causing your IllegalStateException
. You're calling group(1)
without having first called a matching operation (such as find()
). This isn't needed if you're just using $1
since the replaceAll()
is the matching operation.
厄尔的回答为您提供了解决方案,但我想我会添加导致您的IllegalStateException
. 您在group(1)
未首先调用匹配操作(例如find()
)的情况下调用。如果您只是使用$1
,replaceAll()
则不需要,因为是匹配操作。
回答by Mykhaylo Adamovych
Source: java-implementation-of-rubys-gsub
来源:java-implementation-of-rubys-gsub
Usage:
用法:
// Rewrite an ancient unit of length in SI units.
String result = new Rewriter("([0-9]+(\.[0-9]+)?)[- ]?(inch(es)?)") {
public String replacement() {
float inches = Float.parseFloat(group(1));
return Float.toString(2.54f * inches) + " cm";
}
}.rewrite("a 17 inch display");
System.out.println(result);
// The "Searching and Replacing with Non-Constant Values Using a
// Regular Expression" example from the Java Almanac.
result = new Rewriter("([a-zA-Z]+[0-9]+)") {
public String replacement() {
return group(1).toUpperCase();
}
}.rewrite("ab12 cd efg34");
System.out.println(result);
Implementation (redesigned):
实现(重新设计):
import static java.lang.String.format;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class Rewriter {
private Pattern pattern;
private Matcher matcher;
public Rewriter(String regularExpression) {
this.pattern = Pattern.compile(regularExpression);
}
public String group(int i) {
return matcher.group(i);
}
public abstract String replacement() throws Exception;
public String rewrite(CharSequence original) {
return rewrite(original, new StringBuffer(original.length())).toString();
}
public StringBuffer rewrite(CharSequence original, StringBuffer destination) {
try {
this.matcher = pattern.matcher(original);
while (matcher.find()) {
matcher.appendReplacement(destination, "");
destination.append(replacement());
}
matcher.appendTail(destination);
return destination;
} catch (Exception e) {
throw new RuntimeException("Cannot rewrite " + toString(), e);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(pattern.pattern());
for (int i = 0; i <= matcher.groupCount(); i++)
sb.append(format("\n\t(%s) - %s", i, group(i)));
return sb.toString();
}
}
回答by shmosel
Java 9 offers a Matcher.replaceAll()
that accepts a replacement function:
Java 9 提供了一个Matcher.replaceAll()
接受替换函数的方法:
resultString = regexMatcher.replaceAll(
m -> String.valueOf(Integer.parseInt(m.group()) * 3));