Java 替换捕获组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2921212/
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
replace capturing group
提问by Dónal
If I have a regex with a capturing group, e.g. foo(_+f)
. If I match this against a string and want to replace the first capturing group in all matcheswith baz
so that
如果我有一个带有捕获组的正则表达式,例如foo(_+f)
. 如果我符合这个对一个字符串,要替换的第一个捕获组中的所有比赛与baz
使
foo___f blah foo________f
is converted to:
转换为:
foobaz blah foobaz
There doesn't appear to be any easy way to do this using the standard libraries. If I use Matcher.replaceAll()this will replace all matches of the entire pattern and convert the string to
使用标准库似乎没有任何简单的方法可以做到这一点。如果我使用 Matcher.replaceAll()这将替换整个模式的所有匹配项并将字符串转换为
baz blah baz
Obviously I can just iterate through the matches, store the start and end index of each capturing group, then go back and replace them, but is there an easier way?
显然我可以遍历匹配项,存储每个捕获组的开始和结束索引,然后返回并替换它们,但有没有更简单的方法?
Thanks, Don
谢谢,唐
采纳答案by polygenelubricants
I think you want something like this?
我想你想要这样的东西?
System.out.println(
"foo__f blah foo___f boo___f".replaceAll("(?<=foo)_+f", "baz")
); // prints "foobaz blah foobaz boo___f"
Here you simply replace the entire match with "baz"
, but the match uses lookbehind to ensure that _+f
is preceded by foo
.
在这里,您只需将整个匹配替换为"baz"
,但匹配使用后视来确保_+f
前面是foo
。
See also
也可以看看
If lookbehind is not possible (perhaps because the length is not finite), then simply capture even what you're NOT replacing, and refer to them back in the replacement string.
如果后视是不可能的(可能是因为长度不是有限的),那么只需捕获您没有替换的内容,然后在替换字符串中将它们引用回来。
System.out.println(
"fooooo_f boooo_f xxx_f".replaceAll("(fo+|bo+)(_+f)", "baz")
); // prints "fooooobaz boooobaz xxx_f"
So here we're effectively only replacing what \2
matches.
所以在这里我们实际上只替换\2
匹配的内容。
回答by Amarghosh
p = Pattern.compile("foo(g.*?f)");
m = p.matcher("foog___f blah foog________f");
s = m.replaceAll("foobaz");//replace with foobaz instead of just baz
System.out.println(s);//foobaz blah foobaz
回答by Kennet
Is this anywhere close ....
这是附近的任何地方吗....
String[] s = {"foo___f blah foo________f",
"foo___f blah goo________f"};
for(String ss: s)
System.out.println(ss.replaceAll("(foo)(_+)f", "baz"));
Ie, add a capturing group for 'foo' also. Otherwise a simple replacement would be
即,也为“foo”添加一个捕获组。否则一个简单的替换将是
"foo___f blah foo________f".replaceAll("(_+)f", "baz")
回答by Bryce Sandlund
So I don't think any of these answers do justice to more abstract cases of the following question, which is something I ran into myself, so I wrote some code that works in the more general case:
所以我认为这些答案中的任何一个都不能正确处理以下问题的更抽象的情况,这是我自己遇到的问题,所以我编写了一些适用于更一般情况的代码:
/**
*
* @param regex Pattern to find in oldLine. Will replace contents in ( ... ) - group(1) - with newValue
* @param oldLine Previous String that needs replacing
* @param newValue Value that will replace the captured group(1) in regex
* @return
*/
public static String replace(String regex, String oldLine, String newValue)
{
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(oldLine);
if (m.find())
{
return m.replaceAll(replaceGroup(regex, newValue));
}
else
{
throw new RuntimeException("No match");
}
}
/**
* Replaces group(1) ( ... ) with replacement, and returns the resulting regex with replacement String
* @param regex Regular expression whose parenthetical group will be literally replaced by replacement
* @param replacement Replacement String
* @return
*/
public static String replaceGroup(String regex, String replacement)
{
return regex.replaceAll("\(.*\)", replacement);
}
On your example, it does precisely as you describe:
在您的示例中,它完全按照您的描述执行:
String regex = "foo(_+f)";
String line = "foo___f blah foo________f";
System.out.println(FileParsing.replace(regex, line, "baz"));
Prints out:
打印出来:
foobaz blah foobaz