我有这种输入
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();
答案 0 :(得分:11)
您需要在Java中使用Matcher#appendReplacement
才能处理匹配。这是一个例子:
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组:单词char (\w*)
- 第2组:零个或多个字词'
- 单引号(\w(?:'\w)*)
- 第3组:
\w
- 一个字char (?:'\w)*
- 零个或多个序列:
'
- 单引号\w
- 一个字char。现在,如果您想使模式更精确,您可以更改应该与\w
匹配小写字母的\p{Ll}
和应该匹配任何内容的\w
带\p{L}
的信件。该模式看起来像"(?U)\\b(\\p{Ll})(\\p{L}*)'(\\p{Ll}(?:'\\p{Ll})*)"
- 但是,如果在小写字母之前有大写字母(例如在'
- > {{1中),则可能会将字母保留为小写字母(wo'r'D's
之后的字母) }})。 Wo'R'D's
是一个(?U)
内联修饰符,可使Pattern.UNICODE_CHARACTER_CLASS
字边界识别Unicode。
答案 1 :(得分: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();
}
}