2015-11-19 73 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

相關問題