Java replace characters with uppercase around (before and after) specific character

夙愿已清 提交于 2019-12-06 07:31:01

问题


I have this kind of input

word w'ord wo'rd

I need to convert to uppercase both characters at the starts of the word and right after the ' character (which can exists multiple times).

The output I need (using the previous example) is

word W'Ord Wo'Rd

I tried with a simple pattern

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

but I'm unable to convert the group 1 and 3 to uppercase


EDIT: After I discovered a little mistake in the main question, I edited @Wiktor Stribizew code in order to include the case I missed.

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();

回答1:


You need to use Matcher#appendReplacement in Java to be able to process the match. Here is an example:

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

See the Java demo

Java 9+ equivalent (demo):

String s = "wo'rd w'ord wo'r'd";
Matcher m = Pattern.compile("\\b(\\w)(\\w*)'(\\w(?:'\\w)*)").matcher(s);
System.out.println(
    m.replaceAll(r -> r.group(1).toUpperCase()+r.group(2) + "'" + r.group(3).toUpperCase())
);
//wo'rd w'ord wo'r'd => Wo'Rd W'Ord Wo'R'D
//word w'ord wo'rd => word W'Ord Wo'Rd

Pattern break-down:

  • \b - a leading word boundary
  • (\w) - Group 1: a single word char
  • (\w*) - Group 2: zero or more word chars
  • ' - a single quote
  • (\w(?:'\w)*) - Group 3:
    • \w - a word char
    • (?:'\w)* - zero or more sequences of:
      • ' - a single quote
      • \w - a word char.

Now, if you want to make the pattern more precise, you can change the \w that are supposed to match lowercase letters with \p{Ll} and the \w that is supposed to match any letter with \p{L}. The pattern would look like "(?U)\\b(\\p{Ll})(\\p{L}*)'(\\p{Ll}(?:'\\p{Ll})*)" - however, you risk to leave letters in lowercase (those after ') if there are uppercase before lowercase ones (like in wo'r'D's -> Wo'R'D's). (?U) is a Pattern.UNICODE_CHARACTER_CLASS inline modifier that makes \b word boundary Unicode-aware.




回答2:


Not as elegant as @Wiktor Stribizew post above but an attempt to do without regex:

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();
 }
}


来源:https://stackoverflow.com/questions/43467120/java-replace-characters-with-uppercase-around-before-and-after-specific-charac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!