我有这段代码,我想知道,如果我可以只替换组(不是所有模式)在Java正则表达式.代码:
//...
Pattern p = Pattern.compile("(\\d).*(\\d)");
String input = "6 example input 4";
Matcher m = p.matcher(input);
if (m.find()) {
//Now I want replace group one ( (\\d) ) with number
//and group two (too (\\d) ) with 1, but I don't know how.
}
6条答案
按热度按时间368yc8dk1#
使用
$n
(其中n是一个数字)来引用replaceFirst(...)
中捕获的子序列,我假设您想用字符串 "number" 替换第一组,用第一组的值替换第二组。考虑
(\D+)
代替(.*)
作为第二组。*
是一个贪婪的匹配器,首先会消耗最后一位。然后,当匹配器意识到最后的(\d)
没有要匹配的内容时,它将不得不回溯,然后才能匹配到最后一位。多年以后,这个问题仍然得到了投票,评论和编辑(破坏了答案)表明这个问题的含义仍然存在混乱。我已经修复了它,并添加了急需的示例输出。
对替换的编辑(有些人认为不应该使用
$2
)实际上打破了答案。虽然继续的投票显示答案击中了关键点-使用replaceFirst(...)
中的$n
引用来重用捕获的值-编辑失去了这样一个事实,即未修改的文本也需要捕获,并在替换中使用,以便"* 仅分组(而不是所有模式)*"。这个问题,也就是这个答案,与迭代无关,这是有意为之的MRE。
gijlo24d2#
您可以使用
Matcher#start(group)
和Matcher#end(group)
构建一个通用替换方法:检查**online demo here**。
vsmadaxz3#
很抱歉打了一匹死马,但奇怪的是,没有人指出这一点-“是的,你可以,但这是如何在真实的生活中使用捕捉组相反”。
如果您按照Regex的使用方式使用它,解决方案就像这样简单:
或者正如shmosel在下面正确指出的那样,
...因为在正则表达式中根本没有对小数进行分组的好理由。
我们通常不会在字符串中想要 discard 的部分使用 capturing group,而是在字符串中想要 keep 的部分使用它们。
如果你真的想要替换组,你可能需要一个模板引擎(例如moustache、ejs、StringTemplate......)。
顺便说一句,即使是正则表达式中的非捕获组也只是在正则表达式引擎需要它们来识别和跳过变量文本的情况下才存在。
如果你的输入看起来像“abcabccapture mebcdbcd”或者“abccapture mebcd”或者仅仅是“capture me”,你就需要它们。
或者反过来说:如果文本总是相同的,并且您不捕获它,则根本没有理由使用组。
t9eec4r04#
替换输入的密码字段:
u3r8eeie5#
你可以使用matcher.start()和matcher.end()方法来获得组的位置,所以使用这些位置你可以很容易地替换任何文本。
2w2cym1i6#
这里有一个不同的解决方案,它也允许在多个匹配中替换单个组。它使用堆栈来反转执行顺序,因此字符串操作可以安全地执行。