替换Java正则表达式的组1,但不替换整个正则表达式
我有一个只包含一个组的正则表达式模式。我需要在输入字符串中找到符合模式的文本,并只替换匹配组1。例如,我有要应用的正则表达式模式和字符串,如下所示。替换字符串为“” 预期的结果是替换Java正则表达式的组1,但不替换整个正则表达式,java,regex,Java,Regex,我有一个只包含一个组的正则表达式模式。我需要在输入字符串中找到符合模式的文本,并只替换匹配组1。例如,我有要应用的正则表达式模式和字符串,如下所示。替换字符串为“” 预期的结果是 plan p<--->s <--->der p<--->itia 皮塔平面图 我尝试了以下方法 String test = "plan plans lander planitia"; Pattern p = Pattern.compile("\\w*(lan)\\
plan p<--->s <--->der p<--->itia
皮塔平面图
我尝试了以下方法
String test = "plan plans lander planitia";
Pattern p = Pattern.compile("\\w*(lan)\\w+");
Matcher m = p.matcher(test);
String result = "";
while(m.find()){
result = test.replaceAll(m.group(1),"<--->");
}
System.out.print(result);
String test=“plan plans lander planitia”;
模式p=模式。编译(\\w*(lan)\\w+);
匹配器m=p.匹配器(测试);
字符串结果=”;
while(m.find()){
结果=test.replaceAll(m组(1),“”);
}
系统输出打印(结果);
结果如下:
p<---> p<--->s <--->der p<--->itia
psderpitia
另一种方法
String test = "plan plans lander planitia";
Pattern p = Pattern.compile("\\w*(lan)\\w+");
Matcher m = p.matcher(test);
String result = "";
while(m.find()){
result = test.replaceAll("\\w*(lan)\\w+","<--->");
}
System.out.print(result);
String test=“plan plans lander planitia”;
模式p=模式。编译(\\w*(lan)\\w+);
匹配器m=p.匹配器(测试);
字符串结果=”;
while(m.find()){
结果=test.replaceAll(“\\w*(lan)\\w+”,“”);
}
系统输出打印(结果);
结果是
plan <---> <---> <--->
计划
我已经通过了链接。在这里,匹配之前的字符串部分总是常量,并且是“foo”,但在我的例子中,它是变化的。此外,我已经看过了,但我无法应用任何关于我当前场景的解决方案
非常感谢您提供的任何帮助您需要在捕获组时使用以下模式:
(\w*)lan(\w+)
^-1-^ ^-2-^
并替换为$1$2
见
关键是,我们在想要保留的零件周围使用一个捕获组,只匹配想要丢弃的零件 : 看
在这里,由于我们处理一个匹配一个匹配,我们应该只用
replaceFirst
替换组1内容一次,并且因为我们将子字符串替换为一个文本,我们应该模式。引用它。虽然Wiktors对捕获组的使用的解释是完全正确的,但您可以完全避免使用它们。模式开头的\\w*
似乎不相关,因为您希望保留它,因此我们可以将其从模式中删除。检查lan
之后的单词字符可以使用前瞻,如(?=\w)
,因此我们实际上只在“lan(?=\\w)”
等模式中匹配lan
,并且可以使用“
(或任何您喜欢的内容)进行简单替换。要动态控制替换值,请使用循环,使用结束结果
这样你就可以完全控制重置价值。在您的情况下,模式如下,您可以获得指示的位置
开始(1)
↓ 完(一)
↓ ↓
\\w*(局域网)\\w+
↑ ↑
开始()结束()
然后可以提取要保留的值
String input = "plan plans lander planitia";
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("\\w*(lan)\\w+").matcher(input);
while (m.find())
m.appendReplacement(buf, input.substring(m.start(), m.start(1)) +
"<--->" +
input.substring(m.end(1), m.end()));
String output = m.appendTail(buf).toString();
System.out.println(output);
String input=“平面图着陆器平面图”;
StringBuffer buf=新的StringBuffer();
匹配器m=模式。编译(“\\w*(lan)\\w+”)。匹配器(输入);
while(m.find())
m、 appendReplacement(buf,input.substring(m.start(),m.start(1))+
"" +
input.substring(m.end(1),m.end());
字符串输出=m.appendTail(buf).toString();
系统输出打印项次(输出);
输出
皮塔平面图
如果您不喜欢它使用原始字符串,可以使用匹配的子字符串
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("\\w*(lan)\\w+").matcher("plan plans lander planitia");
while (m.find()) {
String match = m.group();
int start = m.start();
m.appendReplacement(buf, match.substring(0, m.start(1) - start) +
"<--->" +
match.substring(m.end(1) - start, m.end() - start));
}
String output = m.appendTail(buf).toString();
StringBuffer buf=new-StringBuffer();
匹配器m=Pattern.compile(“\\w*(lan)\\w+”).Matcher(“平面图着陆器平面图”);
while(m.find()){
字符串匹配=m.group();
int start=m.start();
m、 附件替换(buf,匹配子字符串(0,m.start(1)-开始)+
"" +
match.substring(m.end(1)-start,m.end()-start));
}
字符串输出=m.appendTail(buf).toString();
我喜欢其他解决方案。这是略微优化的防弹版本:
public static void main (String [] args) {
int groupPosition = 1;
String replacement = "foo";
Pattern r = Pattern.compile("foo(bar)");
Matcher m = r.matcher("bar1234foobar1234bar");
StringBuffer sb = new StringBuffer();
while (m.find()) {
StringBuffer buf = new StringBuffer(m.group());
buf.replace(m.start(groupPosition)-m.start(), m.end(groupPosition)-m.start(), replacement);
m.appendReplacement(sb, buf.toString());
}
m.appendTail(sb);
System.out.println(sb.toString()); // result is "bar1234foofoo1234bar"
}
谢谢你的回复。程序将模式作为用户输入,我们要求用户只输入一组模式。所以我们没有固定的模式。有没有办法在不改变模式的情况下做到这一点?我认为这没有意义,但请看一下@WiktorStribiżew,我建议了一个(使用appendReplacement
),但不需要双正则表达式。@Wiktor Stribiżew非常感谢。这就是我要找的。我想我必须多读一些关于Pattern.quote的内容。我以前从未用过。再次感谢。“关键是我们在想要保留的零件周围使用一个捕获组,并与想要丢弃的零件匹配。”。谢谢,伙计。我想指出的是,从性能的角度来看,使用捕获组几乎总是更好的。如果没有特定的上下文要求,也不需要重叠匹配,那么使用正则表达式捕获组是最有效的方法。回答得好@WiktorStribiżew我看不出使用捕获组比前瞻有任何优势。至少我会考虑你的性能更差的解决方案(或者,如果你使用<代码> LAN(\w)),但是如果你喜欢的话,你可以证明相反:(@ @ bb泡:这里,差异是疏忽的。但是,一个捕获组是一个更可读的结构,一些人认为这是使用正则表达式最重要的一点。(我不在其中:)。无论如何,OP对模式没有太多控制权。
String input = "plan plans lander planitia";
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("\\w*(lan)\\w+").matcher(input);
while (m.find())
m.appendReplacement(buf, input.substring(m.start(), m.start(1)) +
"<--->" +
input.substring(m.end(1), m.end()));
String output = m.appendTail(buf).toString();
System.out.println(output);
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("\\w*(lan)\\w+").matcher("plan plans lander planitia");
while (m.find()) {
String match = m.group();
int start = m.start();
m.appendReplacement(buf, match.substring(0, m.start(1) - start) +
"<--->" +
match.substring(m.end(1) - start, m.end() - start));
}
String output = m.appendTail(buf).toString();
public static void main (String [] args) {
int groupPosition = 1;
String replacement = "foo";
Pattern r = Pattern.compile("foo(bar)");
Matcher m = r.matcher("bar1234foobar1234bar");
StringBuffer sb = new StringBuffer();
while (m.find()) {
StringBuffer buf = new StringBuffer(m.group());
buf.replace(m.start(groupPosition)-m.start(), m.end(groupPosition)-m.start(), replacement);
m.appendReplacement(sb, buf.toString());
}
m.appendTail(sb);
System.out.println(sb.toString()); // result is "bar1234foofoo1234bar"
}