重新格式化Java字符串

4

我有一个字符串,看起来像这样:

CALDARI_STARSHIP_ENGINEERING

我需要编辑它,使其看起来像这样

Caldari Starship Engineering

很不幸,现在已经是凌晨三点了,我怎么也无法弄清楚这个问题。我一直都很难处理字符串中的替换内容,所以希望能得到帮助,这将有助于我今后更好地理解如何处理这个问题。


2
过一会儿,polygenelubricants会写一些我不理解的恶毒聪明的正则表达式。 - aioobe
1
@aioobe:如果我的回答不够清晰,我总是非常乐意解释正则表达式,当然,如果人们也知道基础知识,那就更好了。 - polygenelubricants
当然。您总是提供足够的链接等让我理解。我的意思更像是,“polygenelubricants很快会再次用正则表达式给我带来惊喜” :-) 我只是为了好玩写了一个正则表达式版本的解决方案。我相信它对于您所拥有的isEmpty检查是健壮的(但它可能不如您的解决方案高效)。 - aioobe
5个回答

9

像这样的东西很简单:

    String text = "CALDARI_STARSHIP_ENGINEERING";
    text = text.replace("_", " ");
    StringBuilder out = new StringBuilder();
    for (String s : text.split("\\b")) {
        if (!s.isEmpty()) {
            out.append(s.substring(0, 1) + s.substring(1).toLowerCase());
        }
    }
    System.out.println("[" + out.toString() + "]");
    // prints "[Caldari Starship Engineering]"

这个split在单词边界锚上进行。

另请参阅


Matcher 循环解决方案

如果你不介意使用 StringBuffer,你也可以使用 Matcher.appendReplacement/Tail 循环来实现:

    String text = "CALDARI_STARSHIP_ENGINEERING";
    text = text.replace("_", " ");

    Matcher m = Pattern.compile("(?<=\\b\\w)\\w+").matcher(text);
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        m.appendReplacement(sb, m.group().toLowerCase());
    }
    m.appendTail(sb);
    System.out.println("[" + sb.toString() + "]");
    // prints "[Caldari Starship Engineering]"

该正则表达式使用断言来匹配单词的“尾部”部分,即需要小写的部分。它使用后顾断言(?<=...)来查看是否有一个单词边界\b,然后是一个单词字符\w。任何剩余的\w+都需要匹配,以便将其转换为小写。

+1 简单易懂的解决方案,无需使用第三方工具。 - helpermethod
我建议使用 StringBuilder,因为它更快。只有在多线程应用程序中存在并发问题时,才应该使用 StringBuffer 替换 StringBuilder。 - Leni Kirilov
@Leni:不幸的是,Matcher.appendReplacement/Tail 只接受 StringBuffer。如果你想使用 StringBuilder,那么就不能使用这些方法。 - polygenelubricants

4
你可以尝试这个:

你可以尝试这个:

String originalString = "CALDARI_STARSHIP_ENGINEERING";
String newString =
    WordUtils.capitalize(originalString.replace('_', ' ').toLowerCase());

WordUtils 是 Commons Lang 库(http://commons.apache.org/lang/)的一部分。


@In silico - 你假设WordUtils可用并且可以使用。 - Oded
那么,WordUtils是从哪里来的? - aioobe
Apache Commons Lang. org.apache.commons.lang - Amber
编辑它以提到它来自Commons Lang库。 - In silico

1

使用正则表达式:

String s = "CALDARI_STARSHIP_ENGINEERING";
StringBuilder camel = new StringBuilder();
Matcher m = Pattern.compile("([^_])([^_]*)").matcher(s);
while (m.find())
    camel.append(m.group(1)).append(m.group(2).toLowerCase());

0

未经测试,但这是我一段时间以前实现相同功能的方式:

s = "CALDARI_STARSHIP_ENGINEERING";
StringBuilder b = new StringBuilder();
boolean upper = true;
for(char c : s.toCharArray()) {
    if( upper ) {
        b.append(c);
        upper = false;
    } else if( c = '_' ) {
        b.append(" ");
        upper = true;
    } else {
        b.append(Character.toLowerCase(c));
    }
}
s = b.toString();

请注意,EVE许可协议可能禁止编写帮助你职业的外部工具。这可能是让你学习Python的触发器,因为EVE的大部分内容都是用Python编写的 :).

没错 - 如果你改成 else if( c = '_' ) 这样也可以。 - Robben_Ford_Fan_boy
丹尼尔,有EveMon、gtkEveMon、EFT,而且CCP提供了数据库转储和API。 - Travis
哦。我猜你现在不能再玩 Eve 了,除非你有自己的交易监控系统、公会追踪系统之类的? :) - Daniel
嘿,这里有ISK可以赚。能够立即检查哪些项目可以获得最高利润真是太好了...而且还是一个不错的编程项目! - Travis

0

快速而简单的方法:

全部转换为小写

   line.toLowerCase();

分割成单词:

   String[] words = line.split("_");

然后循环遍历单词,将首字母大写:
  words[i].substring(0, 1).toUpperCase() 

需要先将所有字母转换为小写,然后再将首字母大写。 - Robben_Ford_Fan_boy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接