-1

我有一种方法可以将句子中单词的所有首字母转换为大写。

public static String toTitleCase(String s)
{
    String result = "";
    String[] words = s.split(" ");

    for (int i = 0; i < words.length; i++) 
    {
        result += words[i].replace(words[i].charAt(0)+"", Character.toUpperCase(words[i].charAt(0))+"") + " ";
    }

    return result;
}

问题是该方法将与第一个字母相同的单词中的其他字母转换为大写。例如,字符串标题显示为 TiTle

对于输入,this is a title这成为输出This Is A TiTle

我已经尝试了很多东西。一个嵌套循环,检查每个单词中的每个字母,如果有重复出现,则忽略第二个。我使用了计数器、布尔值等。没有任何效果,但我一直得到相同的结果。

我能做些什么?我只想要大写的第一个字母。

4

3 回答 3

3

而不是使用该replace()方法,尝​​试replaceFirst().

result += words[i].replaceFirst(words[i].charAt(0)+"", Character.toUpperCase(words[i].charAt(0))+"") + " ";

将输出:

This Is A Title 
于 2013-11-11T00:29:10.810 回答
0

问题是您正在使用replace替换所有出现的描述字符的方法。要解决此问题,您可以

  • replaceFirst改为使用
    1. 取第一个字母,
    2. 创建它的大写版本
    3. 将它与其余的字符串连接起来,这些字符串可以通过一些substring方法的帮助来创建。
  • 由于您使用replace(String, String)which uses regex 您可以^在要替换的字符之前添加 like replace("^a","A")^表示输入的开始,因此它只会替换a在输入开始之后放置的那个。

我可能会使用第二种方法。


同样,目前在每个循环中,您的代码都会StringBuilder使用存储在 中的数据创建新的result,为其创建append新单词,并重新分配result来自 的输出toString()
这是感染性方法。相反,您应该StringBuilder在循环之前创建将代表您的结果和append在循环内部创建的新单词,在循环结束后,您可以使用toString()方法获取其字符串版本。

于 2013-11-11T00:44:28.400 回答
0

做一些 Regex-Magic 可以简化你的任务:

public static void main(String[] args) {
  final String test = "this is a Test";

  final StringBuffer buffer = new StringBuffer(test);
  final Pattern patter = Pattern.compile("\\b(\\p{javaLowerCase})");
  final Matcher matcher = patter.matcher(buffer);
  while (matcher.find()) {
    buffer.replace(matcher.start(), matcher.end(), matcher.group().toUpperCase());
  }

  System.out.println(buffer);
}

该表达式\\b(\\p{javaLowerCase})匹配“单词的开头后跟一个小写字母”,而matcher.group()等于匹配部分中 () 内的内容。示例:在“t”上应用“test”匹配,因此 start 为 0,end 为 1,group 为“t”。这甚至可以轻松遍历大量文本并替换所有需要替换的字母。

另外:使用 StringBuffer(或类似的)进行字符串操作总是一个好主意,因为 Java 中的每个字符串都是唯一的。也就是说,如果您result += stringPart每次调用它时都执行类似实际创建一个新字符串(等于结果 + stringPart)的操作。因此,如果您使用 10 个部分执行此操作,最终您将在内存中至少有 10 个不同的字符串,而您只需要一个,即最后一个。

StringBuffer 使用类似 char[] 的东西来确保如果您只更改单个字符,则不需要分配额外的内存。

请注意,模式只需要编译一次,因此您可以将其作为类变量保存在某处。

于 2013-11-11T00:57:33.570 回答