Separate string by whitespace, but keep newlines in split array

Viewed 1662

I'm trying to split a string in Java, but keep the newline characters as elements in the array.

For example, with input: "Hello \n\n\nworld!"

I want the output to be: ["Hello", "\n", "\n", "\n", "world", "!"]

The regex I have in place right now is this:
String[] parsed = input.split(" +|(?=\\p{Punct})|(?<=\\p{Punct})");

This gets me the punctuation separation I want, but its output looks like this:
["Hello", "\n\n\nworld", "!"]

Is there a way to unclump the newlines in Java?

3 Answers

You could first replace all \n with \n (newline and a space) and then do a simple split on the space character.

    String input = "Hello \n\n\nworld!";
    String replacement = input.replace("\n", "\n ");
    String[] result = replacement.split(" ");
  • input: "Hello \n\n\nworld!"
  • replacement: "Hello \n \n \n world!"
  • result: ["Hello", "\n", "\n", "\n", "world!"]

Note: my example does not handle the final exclamation mark - but it seems you already know how to handle that.

The trick is to add whitespace after each "\n" and then apply your regex.

    String line = "Hello \n\n\nworld!";
    line = line.replaceAll("\n", "\n "); // here we replace all "\n" to "\n "
    String[] items = line.split(" +|(?=\\p{Punct})|(?<=\\p{Punct})");   

or shorter version:

    String line = "Hello \n\n\nworld!";
    String[] items = line.replaceAll("\n", "\n ").split(" +|(?=\\p{Punct})|(?<=\\p{Punct})");  

So, in this context the result is: ["Hello", "\n", "\n", "\n", "world", "!"]

Using the find method makes things easier:

String str = "Hello \n\n\nworld!";
List<String> myList = new ArrayList<String>();

Pattern pat = Pattern.compile("\\w+|\\H");
Matcher m = pat.matcher(str);

while (m.find()) {
    myList.add(m.group(0));
}

If you use Java 7, change \\H to [\\S\\n].

Note that using this approach, you obtain a pattern easier to write and to edit since you don't need to use lookarounds.

Related