Java 如何替换多个匹配的正则表达式
我有一组正则表达式替换,需要应用于一组字符串 例如:Java 如何替换多个匹配的正则表达式,java,regex,string,Java,Regex,String,我有一组正则表达式替换,需要应用于一组字符串 例如: 具有单个空格的所有多个空格(“\s{2,}”->”) 全部。后面跟着一个带有字符的字符。后跟空格,后跟字符(\。([a-zA-Z]-->“$1”) 所以我会有这样的东西: String s="hello .how are you?"; s=s.replaceAll("\\s{2,}"," "); s=s.replaceAll("\\.([a-zA-Z])",". $1"); .... s = s.replaceAll("\\s{2,
(“\s{2,}”->”)
(\。([a-zA-Z]-->“$1”)
String s="hello .how are you?";
s=s.replaceAll("\\s{2,}"," ");
s=s.replaceAll("\\.([a-zA-Z])",". $1");
....
s = s.replaceAll("\\s{2,}|(\\.)(?=[a-zA-Z])", "$1 ");
它可以工作,但是想象一下,我正在尝试替换一个长字符串上的100多个这样的表达式。不用说这有多慢
所以我的问题是,是否有一种更有效的方法可以用一个replaceAll(或类似的东西,例如Pattern/Matcher)来概括这些替换
我跟着
但问题是我的正则表达式不是
简单字符串
您有以下2个replaceAll
调用:
s = s.replaceAll("\\s{2,}"," ");
s = s.replaceAll("\\.([a-zA-Z])",". $1");
您可以将它们组合成一个replaceAll
,如下所示:
String s="hello .how are you?";
s=s.replaceAll("\\s{2,}"," ");
s=s.replaceAll("\\.([a-zA-Z])",". $1");
....
s = s.replaceAll("\\s{2,}|(\\.)(?=[a-zA-Z])", "$1 ");
查看并修改它
使用地图
- 将数字分组为整数键
- Lambdas作为值
Map<Integer, Function<Matcher, String>> replacements = new HashMap<>() {{
put(1, matcher -> "");
put(2, matcher -> " " + matcher.group(2));
}};
String input = "lorem substr1 ipsum substr2 dolor substr3 amet";
// create the pattern joining the keys with '|'. Need to add groups for referencing later
String regexp = "(\\s{2,})|(\\.(?:[a-zA-Z]))";
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile(regexp);
Matcher m = p.matcher(input);
while (m.find()) {
//TODO change to find which groupNum matched
m.appendReplacement(sb, replacements.get(m.group(groupNum)));
}
m.appendTail(sb);
System.out.println(sb.toString()); // lorem repl1 ipsum repl2 dolor repl3 amet
Map replacements=newhashmap(){{
放置(1,匹配器->“”);
put(2,matcher->“”+matcher.group(2));
}};
字符串输入=“lorem substr1 ipsum substr2 dolor substr3 amet”;
//创建用“|”连接键的模式。需要添加组以供以后参考
字符串regexp=“(\\s{2,})|(\\.(?:[a-zA-Z])”;
StringBuffer sb=新的StringBuffer();
Pattern p=Pattern.compile(regexp);
匹配器m=p.Matcher(输入);
while(m.find()){
//TODO更改以查找匹配的groupNum
m、 appendReplacement(sb,replacements.get(m.group(groupNum));
}
m、 (某人);
System.out.println(sb.toString());//lorem repl1 ipsum repl2 dolor repl3 amet
您可以使用一个大的正则表达式和。但是,您必须非常小心使用您的正则表达式,因为它可能会变得有些混乱,并可能遭受灾难性的回溯。@BoristheSpider如果我使用它,那么我就很难知道使用了哪个正则表达式。不,只需使用捕获组并检查其中有数据。@Boris假设我匹配了。A
我如何知道这是否是使用\\([A-zA-Z])
匹配的。如果您有一个模式,例如(A)|(B)
,那么您知道,当您获得匹配时,第一组或第二组将被填充-另一组将为空(禁用)。你可以用它来确定替换。这是一个很好的观察搭档,但不幸的是,还有许多其他规则不适合这种技术。我根据你所讨论的代码发布了答案。如果你展示更多的代码,那么我可以更好地判断可以做些什么来优化它。thx搭档,有100多条规则,显然是pointl要把它们全部加起来,还有一个([a-zA-Z])\\-,([a-zA-Z])
-->-$1-$2
@nafas这是一个好的解决方案的基础,即使您的表达式是“复杂的”。如果您可以根据常见的替换表达式对所有正则表达式进行分组,那么使用regex替换来链式调用replaceAll()
(如本例中所示),它将尽可能高效。例如s=s.replaceAll(\\s{2,}{124;(\\)(?=[a-zA-Z]),“$1”).replaceAll(“foo | bar | baz”,“qux”).replaceAll…;
@Bohemian我同意,老实说,当anubhava成功地将两者结合起来时,我感到惊讶。这样我可以减少我正在使用的正则表达式的数量,但仍然需要很多repalcell等,我想单行程序或任何更复杂的东西都没有希望了。