java - 正则表达式 - 无法将西里尔字符与 \w 匹配
问题描述
任务:
该任务必须使用正则表达式而不使用容器类来解决。
输入:文本(可能由拉丁文和西里尔文组成)。输出:源文本,但每个单词的第一个字符(由三个或更多字符组成)的大小写必须反转。
将单词视为仅包含字母的序列(单词中不包含所有其他字符)。创建一个将输入转换为输出的静态转换方法。
示例输入数据
When I was younger I never needed Прощай, со всех вокзалов поезда уходят в Дальние Края
示例输出
when I Was Younger I Never Needed прощай, со Всех Вокзалов Поезда Уходят в дальние края
我的尝试:
public static String convert(String input) {
StringBuilder sb = new StringBuilder(input);
Pattern p = Pattern.compile("[\\W&&[\\d]]?[\\w&&[\\D]]+");
Matcher m = p.matcher(input);
while (m.find()) {
if (m.group().length() >= 3) {
if (Character.isUpperCase(sb.charAt(m.start()))) {
sb.setCharAt(m.start(), Character.toLowerCase(sb.charAt(m.start())));
} else {
sb.setCharAt(m.start(), Character.toUpperCase(sb.charAt(m.start())));
}
}
}
return sb.toString();
}
我需要输出:
when I Was Younger
I Never Needed
прощай, со Всех Вокзалов Поезда
Уходят в дальние края
但是我有:
when I Was Younger
I Never Needed
Прощай, со всех вокзалов поезда
уходят в Дальние Края
解决方案
调试问题
\w
不匹配西里尔字符。我通过在您的 while 循环中打印匹配的组来解决这个问题:
System.out.println(m.group());
打印:
当
我 年轻的时候
, 我 从来 不需要
其他词没有一个匹配。
解决方案 1
要匹配西里尔字符,您可以使用\p{L}
. 如果您使用{3}
匹配三个字符,则可以避免在循环中进行长度检查。\b
匹配边界字符。把它们放在一起:
public static String convert(String input) {
StringBuilder sb = new StringBuilder(input);
Pattern p = Pattern.compile("\\b\\p{L}{3}");
Matcher m = p.matcher(input);
while (m.find()) {
char firstChar = sb.charAt(m.start());
if (Character.isUpperCase(firstChar)) {
sb.setCharAt(m.start(), Character.toLowerCase(firstChar));
} else {
sb.setCharAt(m.start(), Character.toUpperCase(firstChar));
}
}
return sb.toString();
}
产生:
当我 年轻时
我从来不需要
прощай, со Всех Вокзалов Поезда
Уходят в дальние края
解决方案 2
或者,如果你想要真正的嗖嗖声,请使用正向前瞻(非捕获组)和replaceAll
采用 lambda 的 matcher 方法:
public static String convert(String input) {
Pattern p = Pattern.compile("\\b(\\p{L})(?=\\p{L}{2})");
Matcher m = p.matcher(input);
return m.replaceAll(match -> {
char ch = match.group().charAt(0);
if (Character.isUpperCase(ch)) {
return "" + Character.toLowerCase(ch);
}
return "" + Character.toUpperCase(ch);
});
}
还产生:
当我 年轻时
我从来不需要
прощай, со Всех Вокзалов Поезда
Уходят в дальние края
推荐阅读
- python - 没有为 Pandas 查询功能定义“BACKTICK_QUOTED_STRING__AT_key”
- asp.net-core - Odata 扩展总是生成左连接
- ios - 当它不是可访问性元素时,是否可以通过其 `accessibilityId` 获取`XCUIElement`?
- android - 一次性权限导致后台计划作业和警报被取消
- reactjs - 警告:validateDOMNesting(...):不能作为. 在 gatsby js 项目中
- discord.py - 用户权限检查抛出错误,但我不知道为什么
- java - Android - 如何访问 PDF 页面的属性?
- glassfish - Payara 服务器作为服务启动
- sql - 从具有面积总和的表中选择查询
- javascript - 优化缩小 JS 的 TypeScript 编译和调试