简体   繁体   English

字符串中单词的大写

[英]Capitalization of the words in string

How can I avoid of StringIndexOutOfBoundsException in case when string starts with space (" ") or when there're several spaces in the string?如果字符串以空格 (" ") 开头或字符串中有多个空格,如何避免 StringIndexOutOfBoundsException? Actually I need to capitalize first letters of the words in the string.实际上,我需要将字符串中单词的首字母大写。

My code looks like:我的代码看起来像:

public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = reader.readLine();
    String[] array = s.split(" ");

    for (String word : array) {
        word = word.substring(0, 1).toUpperCase() + word.substring(1); //seems that here's no way to avoid extra spaces
        System.out.print(word + " ");
    }
}

Tests:测试:

Input: "test test test"输入: "test test test"

Output: "Test Test Test"输出: "Test Test Test"


Input: " test test test"输入: " test test test"

Output:输出:

StringIndexOutOfBoundsException

Expected: " Test Test test"预期: " Test Test test"

I'm a Java newbie and any help is very appreciated.我是 Java 新手,非常感谢您的帮助。 Thanks!谢谢!

split will try to break string in each place where delimiter is found. split将尝试在找到分隔符的每个位置断开字符串。 So if you split on space and space if placed at start of the string like因此,如果您将空格和空格分开放置在字符串的开头,例如

" foo".split(" ")

you will get as result array which will contain two elements: empty string "" and "foo"您将获得包含两个元素的结果数组:空字符串“”和“foo”

["", "foo"]

Now when you call "".substring(0,1) or "".substring(1) you are using index 1 which doesn't belong to that string.现在,当您调用"".substring(0,1)"".substring(1)您正在使用不属于该字符串的索引1

So simply before you do any String modification based on indexes check if it is safe by testing string length.因此,在您根据索引进行任何字符串修改之前,只需通过测试字符串长度检查它是否安全。 So check if word you are trying to modify has length grater than 0, or use something more descriptive like if(!word.isEmpty()) .因此,请检查您尝试修改的单词的长度是否大于 0,或者使用更具描述性的内容,例如if(!word.isEmpty())

与其拆分字符串,不如尝试简单地遍历原始字符串中的所有字符,用大写替换所有字符,以防它是该字符串的第一个字符或其前身是空格。

A slight modification to Capitalize first word of a sentence in a string with multiple sentences .具有多个句子的字符串中的句子的第一个单词进行大写的轻微修改。

public static void main( String[] args ) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = reader.readLine();

    int pos = 0;
    boolean capitalize = true;
    StringBuilder sb = new StringBuilder(s);
    while (pos < sb.length()) {
        if (sb.charAt(pos) == ' ') {
            capitalize = true;
        } else if (capitalize && !Character.isWhitespace(sb.charAt(pos))) {
            sb.setCharAt(pos, Character.toUpperCase(sb.charAt(pos)));
            capitalize = false;
        }
        pos++;
    }
    System.out.println(sb.toString());
}

I would avoid using split and go with StringBuilder instead.我会避免使用 split 并使用 StringBuilder 代替。

在拆分中使用正则表达式拆分所有空格

String[] words = s.split("\\s+");

Easier would be to use existing libraries: WordUtils.capitalize(str) (from apache commons-lang ).使用现有库更容易: WordUtils.capitalize(str) (来自apache commons-lang )。


To fix your current code however, a possible solution would be to use a regex for words ( \\\\w ) and a combination of StringBuffer / StringBuilder setCharAt and Character.toUpperCase :然而,要修复您当前的代码,一个可能的解决方案是使用正则表达式( \\\\w )和StringBuffer / StringBuilder setCharAtCharacter.toUpperCase的组合:

public static void main(String[] args) {
    String test = "test test   test";

    StringBuffer sb = new StringBuffer(test);
    Pattern p = Pattern.compile("\\s+\\w"); // Matches 1 or more spaces followed by 1 word
    Matcher m = p.matcher(sb);

    // Since the sentence doesn't always start with a space, we have to replace the first word manually
    sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
    while (m.find()) {
      sb.setCharAt(m.end() - 1, Character.toUpperCase(sb.charAt(m.end() - 1)));
    }

    System.out.println(sb.toString());
}

Output:输出:

Test Test   Test

Capitalize whole words in String using native Java streams使用原生 Java 流将字符串中的整个单词大写

It is really elegant solution and doesnt require 3rd party libraries这是非常优雅的解决方案,不需要第 3 方库

    String s = "HELLO, capitalized worlD! i am here!     ";
    CharSequence wordDelimeter = " ";

    String res = Arrays.asList(s.split(wordDelimeter.toString())).stream()
          .filter(st -> !st.isEmpty())
          .map(st -> st.toLowerCase())
          .map(st -> st.substring(0, 1).toUpperCase().concat(st.substring(1)))
          .collect(Collectors.joining(wordDelimeter.toString()));

    System.out.println(s);
    System.out.println(res);

The output is输出是

HELLO, capitalized worlD! i am here!     
Hello, Capitalized World! I Am Here!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM