我想删除每个出现的"*"
,但忽略"**"
,因此,例如,如果我有"testing *single star* and **double star**"
,删除后的句子将是"testing single star and **double star**"
。有没有办法根据出现次数来替换子字符串?
我正在考虑使用replace("*", "")
,但是当我试过时,它就摆脱了所有的星星。
我该怎么办?
我想删除每个出现的"*"
,但忽略"**"
,因此,例如,如果我有"testing *single star* and **double star**"
,删除后的句子将是"testing single star and **double star**"
。有没有办法根据出现次数来替换子字符串?
我正在考虑使用replace("*", "")
,但是当我试过时,它就摆脱了所有的星星。
我该怎么办?
您可以利用lookarounds
String s = "testing *single star* and **double star**".replaceAll("(?<![*])[*](?![*])", "");
见IDEONE demo(结果:testing single star and **double star**
)
把*
为角色类允许在没有逃脱匹配一个星号。
(?<![*])
是一个否定的后视检查,检查星号前是否没有星号,(?![*])
是否定的前视,确保星号匹配后没有星号。
你也许可以用
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 两个或更多星(但不是一个)。
我认为你可以将这种方法描述为“取出奇数星号”(因此,1变成0,2和3,2,4和5到4等)。 Mine有点不同,因为它只删除用非星号符号包围的1星号序列。无论如何,体育精神就是我所追求的:) –
@stribizhev是的,*奇*或与我的职位末尾描述的变化*超过2 * :) – Pshemo
我们是否应该考虑用3星的输入?如果是这样,那么你想如何处理它们? – Pshemo
@Pshemo 3星不需要考虑,但stribizhev的答案似乎适用于所有情况。 – silverAndroid