2

This question was asked several times before but I couldn't find an answer to my question: I need to split a string into two strings. First part is date and the second string is text. This is what i got so far:

String test = "24.12.17 18:17 TestString";
String[] testSplit = test.split("\\d{2}.\\d{2}.\\d{2} \\d{2}:\\d{2}");
System.out.println(testSplit[0]);           // "24.12.17 18:17" <-- Does not work
System.out.println(testSplit[1].trim());    // "TestString" <-- works

I can extract "TestString" but i miss the date. Is there any better (or even simpler) way? Help is highly appreciated!

2
  • Is your string always a date with this format followed by an arbitrary text? Commented Aug 12, 2017 at 17:40
  • There is an easy way if you don't bother relying on the fact that the date & time has a constant length. Commented Aug 12, 2017 at 17:40

3 Answers 3

3

Skip regex; Use three strings

You are working too hard. No need to include the date and the time together as one. Regex is tricky, and life is short.

Just use the plain String::split for three pieces, and re-assemble the date-time.

String[] pieces = "24.12.17 18:17 TestString".split( " " ) ;  // Split into 3 strings.
LocalDate ld = LocalDate.parse( pieces[0] , DateTimeFormatter.ofPattern( "dd.MM.uu" ) ) ;  // Parse the first string as a date value (`LocalDate`).
LocalTime lt = LocalTime.parse( pieces[1] , DateTimeFormatter.ofPattern( "HH:mm" ) ) ;  // Parse the second string as a time-of-day value (`LocalTime`).
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;  // Reassemble the date with the time (`LocalDateTime`).
String description = pieces[2] ;  // Use the last remaining string. 

See this code run live at IdeOne.com.

ldt.toString(): 2017-12-24T18:17

description: TestString

Tip: If you have any control over that input, switch to using standard ISO 8601 formats for date-time values in text. The java.time classes use the standard formats by default when generating/parsing strings.

Sign up to request clarification or add additional context in comments.

Comments

2

You want to match only the separator. By matching the date, you consume it (it's thrown away).

Use a look behind, which asserts but does not consume:

test.split("(?<=^.{14}) ");

This regex means "split on a space that is preceded by 14 characters after the start of input".


Your test code now works:

String test = "24.12.17 18:17 TestString";
String[] testSplit = test.split("(?<=^.{14}) ");
System.out.println(testSplit[0]);           // "24.12.17 18:17" <-- works
System.out.println(testSplit[1].trim());    // "TestString" <-- works

1 Comment

Why the downvote? This exactly answers the question and works perfectly.
2

If your string is always in this format (and is formatted well), you do not even need to use a regex. Just split at the second space using .substring and .indexOf:

String test = "24.12.17 18:17 TestString";
int idx = test.indexOf(" ", test.indexOf(" ") + 1);
System.out.println(test.substring(0, idx));
System.out.println(test.substring(idx).trim());

See the Java demo.

If you want to make sure your string starts with a datetime value, you may use a matching approach to match the string with a pattern containing 2 capturing groups: one will capture the date and the other will capture the rest of the string:

String test = "24.12.17 18:17 TestString";
String pat = "^(\\d{2}\\.\\d{2}\\.\\d{2} \\d{2}:\\d{2})\\s(.*)";
Matcher matcher = Pattern.compile(pat, Pattern.DOTALL).matcher(test);
if (matcher.find()) {
    System.out.println(matcher.group(1));
    System.out.println(matcher.group(2).trim());
}

See the Java demo.

Details:

  • ^ - start of string
  • (\\d{2}\\.\\d{2}\\.\\d{2} \\d{2}:\\d{2}) - Group 1: a datetime pattern (xx.xx.xx xx:xx-like pattern)
  • \\s - a whitespace (if it is optional, add * after it)
  • (.*) - Group 2 capturing any 0+ chars up to the end of string (. will match line breaks, too, because of the Pattern.DOTALL flag).

4 Comments

This doesn't actually answer the question, which asks "I need to split a string into two strings"
@Bohemian It does answer that question. It does split a string that starts with a specific pattern into two parts. If you can prove the opposite I will remove the answer.
The "proof" is the absence of split anywhere in your code and there is no String[] result. You could create a String[] somewhere in your code and assign values to its elements, but at that point you might as well code String[] testResult = new String[2]; testResult[0] = test.substring(0, 14); testResult[1] = test.substring(15); which is much less code than your answer, and simpler, but still doesn't split the string. See my answer for a simple, elegant solution that actually splits the input as requested.
@Bohemian: There is no requirement in the question to use split(). Split means getting parts of a whole, and my code does it. There are several points that prove my solution is better than yours: 1) my solution makes sure we actually have a datetime at the start of the string, 2) if there is no whitespace between the datetime and the rest of the string, my solution will work, yours requires a space, 3) my solution will work even if there is any whitespace, not just a regular space between the datetime and the rest of the string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.