替换使用正则表达式与Java

问题描述:

多个捕获组我有这样的要求 - 用于将输入的字符串,如下面替换使用正则表达式与Java

8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs 

所示的我想剥离匹配字边界(其中匹配对是8或&或%等),将导致用于对字符可以变化例如以下

This is really a test of repl%acing %mul%tiple matched 9pairs 

此列表8,9,%,#等,并且只有与每种类型的开始和结束相匹配的单词将被剥离这些字符,其中嵌入单词中的相同字符保留在其中。

使用的Java我可以做一个图案\\b8([^\\s]*)8\\b和替换为$ 1,捕捉和替换所有出现的8 ... 8,但我要如何做到这一点的所有类型的对?

我可以提供诸如\\b8([^\\s]*)8\\b|\\b9([^\\s]*)9\\b模式..等,将符合所有类型的匹配对* 8,9,...),但我怎么指定一个“变量”取代基团 -

例如如果比赛是9 ... 9,则替换应该是2美元。

我当然可以通过其中的多个运行它,每个代替特定类型的对,但我想知道是否有更优雅的方式。

还是有一个完全不同的方式来解决这个问题?

谢谢。

你可以使用下面的正则表达式,然后由目前集团索引2

(?<!\S)(\S)(\S+)\1(?=\s|$) 

OR

(?<!\S)(\S)(\S*)\1(?=\s|$) 

Java的正则表达式将是

(?<!\\S)(\\S)(\\S+)\\1(?=\\s|$) 
里面的人物更换匹配的字符

DEMO

String s1 = "8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs"; 
System.out.println(s1.replaceAll("(?<!\\S)(\\S)(\\S+)\\1(?=\\s|$)", "$2")); 

输出:

This is reallly a test of repl%acing %mul%tiple matched 9pairs 

说明:

  • (?<!\\S)负回顾后,断言匹配不会由非空格字符之前。
  • (\\S)捕获第一个非空格字符并将其存储到组索引1中。
  • (\\S+)捕获一个或多个非空格字符。
  • \\1指第一个捕获组内的字符。
  • (?=\\s|$)而且匹配后面必须跟一个空格或行尾的结束符。
  • 这确保字符串的第一个字符和最后一个字符必须相同。如果是这样,那么它通过其存在的组索引2

对于这个特定的情况下,内部的字符替换整个匹配,可以修改上述正则表达式为,

String s1 = "8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs"; 
System.out.println(s1.replaceAll("(?<!\\S)([89&#%])(\\S+)\\1(?=\\s|$)", "$2")); 

DEMO

+1

谢谢。按照你和另一个人的建议,使用后向参照和捕获组2似乎已经对它进行了固定。我正在使用以下(? ssen 2014-12-11 05:48:56

+0

@ssen正是你得到的。更多的减少了一个'(? 2014-12-11 05:56:49

(?<![a-zA-Z])[8&#%9](?=[a-zA-Z])([^\s]*?)(?<=[a-zA-Z])[8&#%9](?![a-zA-Z]) 

试试这个。用$1\1替换。参见demo。

https://regex101.com/r/qB0jV1/15

(?<![a-zA-Z])[^a-zA-Z](?=[a-zA-Z])([^\s]*?)(?<=[a-zA-Z])[^a-zA-Z](?![a-zA-Z]) 

使用这个,如果你有很多的分隔符。