Victor Olaitan
Victor Olaitan

Reputation: 79

Can't seem to split String by new line regex

I have this method, and it will not correctly add the split string to my list.

public static List<String> formatConfigMessages(FileConfiguration config, String key, boolean colour, Object... regex) {
    List<String> messages = new ArrayList<>();
    if (config.isList(key)) {
        config.getStringList(key).forEach(message -> {
            if (message.contains("\\n")) {
                Collections.addAll(messages, message.split("\\r\\n|\\n|\\r"));
            } else {
                messages.add(message);
            }
        });
    } else {
        String message = config.getString(key);
        if (message.contains("\\n")) {
            Collections.addAll(messages, message.split("\\r\\n|\\n|\\r"));
        } else {
            messages.add(message);
        }
    }
    return messages.stream().map(message -> formatMessage(message, colour, regex)).collect(Collectors.toList());
}

For a bit of context, this method is used to format configurable messages for my SpigotMC plugin. The method takes 4 parameters:

  1. FileConfiguration - A class made to simplify the use of YAML configuration files.
  2. String - the key of the message (can be indexed with '.', either side of the '.' represents a different level of the YAML file).
  3. Boolean - whether or not reserved characters in the string should be converted into coloured characters (colours can only be seen by the client)
  4. Object... - some patterns, etc.) <name> to be replaced with the following value in the array.

That is the chunk of code that won't work. Initially, I attempted to set the regex as \n, but that didn't return a list. I assumed this was because it was searching for already parsed new lines rather than the '\n' stream of characters. So I changed my regex to \n, which still didn't work. I search the internet and found in this post that I should use the regex \\r\\n as well as \\n because \r is used on Windows systems. This again did not work, and I keep getting 1 string with the \n still inside.

Upvotes: 1

Views: 817

Answers (1)

Salem
Salem

Reputation: 14917

Here's why.

Regex has its own escape sequences, denoted with \\ (the escape sequence for \), since Java reserves \.

For example, \\w denotes any character in a word.

To split by "\n", you'll need \\\\n instead, because \\n in regex represents an actual line break, just as \n represents one in Java.

Example:

System.out.println(Arrays.toString("Hello\\nworld".split("\\\\n")));
System.out.println(Arrays.toString("Hello world\nwith newline".split("\\n")));
System.out.println(Arrays.toString("Hello world\nwith newline".split("\n")));
System.out.println(Arrays.toString("I won't\\nsplit".split("\\n")));

Prints:

[Hello, world]
[Hello world, with newline]
[Hello world, with newline] <-- Same effect as above
[I won't\nsplit]

Additionally, to handle all three line end types (though \r on its own is uncommon nowadays), use the regex \\\\r?\\\\n|\\\\r instead.

Upvotes: 1

Related Questions