2015-11-19 48 views
1

我想删除每个出现的"*",但忽略"**",因此,例如,如果我有"testing *single star* and **double star**",删除后的句子将是"testing single star and **double star**"有没有办法根据出现次数来替换子字符串?

我正在考虑使用replace("*", ""),但是当我试过时,它就摆脱了所有的星星。

我该怎么办?

+1

我们是否应该考虑用3星的输入?如果是这样,那么你想如何处理它们? – Pshemo

+0

@Pshemo 3星不需要考虑,但stribizhev的答案似乎适用于所有情况。 – silverAndroid

回答

7

您可以利用lookarounds

String s = "testing *single star* and **double star**".replaceAll("(?<![*])[*](?![*])", ""); 

IDEONE demo(结果:testing single star and **double star**

*为角色类允许在没有逃脱匹配一个星号。

(?<![*])是一个否定的后视检查,检查星号前是否没有星号,(?![*])是否定的前视,确保星号匹配后没有星号。

3

你也许可以用

yourString = yourString.replaceAll("(\\*{2})|\\*","$1"); 

说明尝试:replaceAll使用正则表达式(正则表达式)的机制。另外*是正则表达式中的特殊字符,所以我们需要转义它(我使用\\*来做到这一点,但您也可以使用[*]或用\\Q\\E包围它)。现在让我们来看看这是什么正则表达式是:

  • (\\*{2}) - 将尝试匹配**,并将其放置在第1组
  • | - OR操作
  • \\* - 比赛只有一个*

所以此解决方案将尝试首先找到**,将其存储在组1中,稍后用组1中的匹配替换它(因此我们将其替换为它自己,这意味着它们将保留在文本中)。
但是,如果正则表达式引擎将无法找到**,而是会找到*,组1将是空的,因为它只能匹配两颗星(因为该部分正则表达式被圆括号包围)。所以我们的替换$1将代表空字符串,这意味着我们将删除单个*

所以,目前的解决方案会引起这些变化:

*  ->  - found 1 star (remove it) 
** -> ** - found 2 stars (stay) 
*** -> ** - found 2 stars (stay), 1 star (remove) 
**** -> **** - found 2 stars (stay), 2 stars (stay) 
***** -> **** - found 2 stars (stay), 2 stars (stay) and 1 star (remove) 

如果你不想影响2个或更多的恒星(如***应该仍然是***),而不是{2}使用{2,},这将允许我们存储组1 两个或更多星(但不是一个)。

+0

我认为你可以将这种方法描述为“取出奇数星号”(因此,1变成0,2和3,2,4和5到4等)。 Mine有点不同,因为它只删除用非星号符号包围的1星号序列。无论如何,体育精神就是我所追求的:) –

+0

@stribizhev是的,*奇*或与我的职位末尾描述的变化*超过2 * :) – Pshemo

相关问题