我有这种输入
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();
最佳答案
您需要在 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
Java 9+ 等效项(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
模式分解:
\b
- 前导词边界(\w)
- 第 1 组:单个单词字符(\w*)
- 第 2 组:零个或多个单词字符'
- 单引号(\w(?:'\w)*)
- 第 3 组:\w
- 一个字符(?:'\w)*
- 零个或多个序列:'
- 单引号\w
- 一个字符。
现在,如果你想让模式更精确,你可以将应该与小写字母匹配的 \w
更改为 \p{Ll}
和\w
应该匹配任何带有 \p{L}
的字母。该模式看起来像 "(?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。
关于Java用大写字母替换特定字符周围(之前和之后)的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43467120/