Java 用大写字母替换特定字符前后的字符
Java replace characters with uppercase around (before and after) specific character
我有这样的输入法
word w'ord wo'rd
我需要将单词开头和 '
字符(可以存在多次)之后的两个字符都转换为大写。
我需要的输出(使用前面的例子)是
word W'Ord Wo'Rd
我尝试了一个简单的模式
s.replaceAll("(\w)(\w*)'(\w)", "");
但我无法将第 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 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 组:单个单词 char
(\w*)
- 第 2 组:零个或多个单词字符
'
- 单引号
(\w(?:'\w)*)
- 第 3 组:
\w
- 一个字 char
(?:'\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。
不如上面的 @Wiktor Stribizew post 优雅,但尝试不使用正则表达式:
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();
}
}
我有这样的输入法
word w'ord wo'rd
我需要将单词开头和 '
字符(可以存在多次)之后的两个字符都转换为大写。
我需要的输出(使用前面的例子)是
word W'Ord Wo'Rd
我尝试了一个简单的模式
s.replaceAll("(\w)(\w*)'(\w)", "");
但我无法将第 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 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 组:单个单词 char(\w*)
- 第 2 组:零个或多个单词字符'
- 单引号(\w(?:'\w)*)
- 第 3 组:\w
- 一个字 char(?:'\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。
不如上面的 @Wiktor Stribizew post 优雅,但尝试不使用正则表达式:
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();
}
}