2017-04-18 94 views
2

我有這種投入Java的大寫字符替換左右(前後)特定字符

word w'ord wo'rd 

我需要轉換爲大寫的單詞的開始和'字符後右兩個字符(它可以存在多次)。

我需要的輸出(使用前面的例子)是

word W'Ord Wo'Rd 

我試圖用一個簡單的圖案

s.replaceAll("(\\w)(\\w*)'(\\w)", "$1"); 

但我無法將第1組和第3轉換爲大寫


編輯: 在我發現主要問題的一個小錯誤後,我編輯@Wiktor Stribizew代碼,以包括我錯過的情況。

Matcher m = Pattern.compile("(\\w)(\\w*)'(\\w)").matcher(s); 
StringBuffer result = new StringBuffer(); 
while (m.find()) { 
    m.appendReplacement(result, m.group(1).toUpperCase() + m.group(2) + "'" + m.group(3).toUpperCase()); 
} 
m.appendTail(result); 
s = result.toString(); 

回答

9

您需要使用Matcher#appendReplacement在Java能夠處理比賽。這裏有一個例子:

String s = "word w'ord wo'rd"; 
StringBuffer result = new StringBuffer(); 
Matcher m = Pattern.compile("\\b(\\w)(\\w*)'(\\w(?:'\\w)*)").matcher(s); 
while (m.find()) { 
    m.appendReplacement(result, 
     m.group(1).toUpperCase()+m.group(2) + "'" + m.group(3).toUpperCase()); 
} 
m.appendTail(result); 
System.out.println(result.toString()); 
// => word W'Ord Wo'Rd 

Java demo

模式擊穿

  • \b - 領先字邊界
  • (\w) - 第1組:一個字,字符
  • (\w*) - 第2組:零個或多個字字符
  • ' - 單引號
  • (\w(?:'\w)*) - 第3組:
    • \w - 一個字炭
    • (?:'\w)* - 零個或更多序列:
      • ' - 單引號
      • \w - 一個字的字符。

現在,如果你想使圖案更精確,你可以改變,都應該與\p{Ll}匹配小寫字母\w和應該匹配\p{L}任何字母\w 。該模式將類似於"(?U)\\b(\\p{Ll})(\\p{L}*)'(\\p{Ll}(?:'\\p{Ll})*)" - 然而,你可能要離開小寫字母(那些'後),如果有大寫小寫的人之前(如在wo'r'D's - >Wo'R'D's)。 (?U)是一個Pattern.UNICODE_CHARACTER_CLASS行內修飾符,它使\b字邊界可識別Unicode。

+0

這工作確實。運行這段代碼並在所有需要轉換的行上看到輸出,我發現主要問題中存在一個小錯誤。我現在調整了主要問題,以包括我錯過的情況 –

+0

字符串失敗:\t String s =「wo'rd w'ord wo'r'd」; – Optional

+0

@DevilingMaster:同樣的方法在這裏是有效的:將你需要的東西捕獲到組中,然後在'while'塊內按照需要操作每個組。 –

0

不一樣優雅的@Wiktor Stribizew後上方,但企圖沒有正則表達式的事情:

public class HelloWorld{ 

public static void main(String []args){ 
    String s ="word w'ord wo'r'd"; 
    System.out.println(upperCase(s,'\'')); 
} 
private static int x = 1; 
private static String upperCase(String originalString, char delimeter) 
{ 
    if(originalString.length()==1) 
    { 
     return originalString; 
    } 
    int indexOfDelimeter = originalString.indexOf(delimeter); 
    StringBuilder result = new StringBuilder(); 
    if(indexOfDelimeter<0) 
    { 
     return originalString; 
    } 
    String newBaseString = originalString.substring(indexOfDelimeter+2); 
    if(indexOfDelimeter==0) 
    { 
     result.append(delimeter).append(Character.toUpperCase(originalString.charAt(indexOfDelimeter+1))).append(newBaseString); 
    } 
    else 
    { 
     result.append(originalString.substring(0,indexOfDelimeter-1)).append(Character.toUpperCase(originalString.charAt(indexOfDelimeter-1))).append(delimeter).append(Character.toUpperCase(originalString.charAt(indexOfDelimeter+1))); 
    } 
    if(indexOfDelimeter<originalString.length()) 
    { 
     result.append(upperCase(newBaseString,delimeter)); 
    } 
    return result.toString(); 
} 
}