2017-08-12 89 views
2

以前曾经问过几次这个问题,但我找不到我的问题的答案: 我需要将字符串拆分为两个字符串。第一部分是日期,第二部分是文本。这是我到目前为止:用正则表达式将字符串拆分为两个字符串

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 

我可以提取“TestString”,但我想念日期。有没有更好的(或者更简单)方法?非常感谢帮助!

+0

您的字符串是否始终是此格式的日期,后面是任意文本? – pchaigno

+0

如果你不打扰依靠日期和时间长度不变的事实,那么有一种简单的方法。 –

回答

2

你想匹配只有分隔符。通过匹配日期,你消耗它(它被扔掉了)。

使用看后面,它断言,但不消耗:

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

此正则表达式的意思是“在由14个字符输入开始后前面有一个空格分割”。


你的测试代码现在工作:

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 
+2

为什么downvote?这完全回答了这个问题,并且完美地运作 – Bohemian

2

如果你的字符串始终以这种格式(和格式化好),你甚至都不需要使用正则表达式。只是在拆分使用.substring.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()); 

Java demo

如果你想确保你的字符串日期时间值开始,你可以使用一个匹配的方法来串用含2个捕获组匹配的模式:一个将捕获的日期和其他将捕获休息的字符串:

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()); 
} 

查看Java demo

详细

  • ^ - 字符串的开始
  • (\\d{2}\\.\\d{2}\\.\\d{2} \\d{2}:\\d{2}) - 第1组:日期时间模式(xx.xx.xx xx:xx样模式)
  • \\s - 一个空格(如果是可选的,加之后的*
  • (.*) - 第2组捕获任何0+字符直到字符串结尾(.也会匹配换行符,因为Pattern.DOTALL标志)。
+1

这实际上并没有回答问题,它询问*“我需要将一个字符串分成两个字符串”* – Bohemian

+1

@Bohemian它**确实**回答该问题。它**不会**将一个以特定模式开始的字符串分成**两个**部分。如果你能证明相反,我会删除答案。 –

+1

“证明”是代码中没有'split',并且没有'String []'结果。你可以在你的代码的某个地方创建一个String []并为它的元素赋值,但是在那一点你可能也会使用代码String [] testResult = new String [2]; testResult [0] = test.substring(0,14); testResult [1] = test.substring(15);'这是比你的答案少得多的代码,并且更简单,但是仍然不分割字符串。看到我的答案是一个简单,优雅的解决方案,实际上按要求分割输入。 – Bohemian

3

跳过正则表达式;使用三个字符串

您正在努力工作。无需将日期和时间合并为一个。正则表达式很棘手,而且生命短暂。

只需使用普通的String::split三个件,并重新组装日期时间。

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. 

看到这个code run live at IdeOne.com

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

描述:的TestString

提示:如果有超过该输入任何控制,切换到使用标准ISO 8601格式日期时间值在文本中。在生成/解析字符串时,java.time类默认使用标准格式。