【问题标题】:How can I parse string using square brackets as a delimiter in Java?如何在 Java 中使用方括号作为分隔符来解析字符串?
【发布时间】:2016-10-05 03:15:24
【问题描述】:

我有一个使用.split() 解析 ZonedDateTime 对象的类,以消除所有我不想要的额外信息。

我的问题:有没有办法使用方括号作为我缺少的分隔符,或者如何在不使用方括号的情况下自行获取时区([US/Mountain])分隔符?

我希望字符串时区看起来像“US/Mountian”或“[US/Mountian]

我的尝试: 我试过wholeThing.split("[[-T:.]]?)wholeThing.split("[%[-T:.%]]") 但它们都给了我00[US/Mountain]

我也尝试过wholeThing.split("[\\[-T:.\\]])wholeThing.split("[\[-T:.\]"),但这些只会给我错误。

(部分)我的代码:

 //We start out with something like   2016-09-28T17:38:38.990-06:00[US/Mountain]

    String[] whatTimeIsIt = wholeThing.split("[[-T:.]]"); //wholeThing is a TimeDateZone object converted to a String
    String year = whatTimeIsIt[0];
    String month = setMonth(whatTimeIsIt[1]);
    String day = whatTimeIsIt[2];
    String hour = setHour(whatTimeIsIt[3]);
    String minute = whatTimeIsIt[4];
    String second = setAmPm(whatTimeIsIt[5],whatTimeIsIt[3]);
    String timeZone = whatTimeIsIt[8];

【问题讨论】:

  • 为什么不使用 .... 解析 ZonedDateTime 字符串,你知道 .... ZonedDateTime.parse()? ---无论如何,您的问题不清楚您想要什么输出。您希望timeZone 字符串是什么? -06:00? US/Mountain?请说清楚。 --- 但是,最好使用 正则表达式,而不是尝试使用split(),即使用PatternMatcher,这样您就可以使用@ 获得适当的部分987654335@ 方法。如果你不知道正则表达式,现在是学习的时候了。
  • 澄清一下,您希望能够从字符串中获取时区吗?
  • 编辑澄清
  • @andreas 因为我想自己练习,而且 ZonedDateTime.parse() 并不能完全满足我的要求。我的课是这样,除了我坚持的这一部分。
  • 好奇:ZonedDateTime.parse() 怎么不给你你想要的?

标签: java split zoneddatetime


【解决方案1】:

使用split() 是正确的想法。

String[] timeZoneTemp = wholeThing.split("\\[");
String timeZone = timeZoneTemp[1].substring(0, timeZoneTemp[1].length() - 1);

【讨论】:

  • 第一行给了我错误“未封闭的字符类”
  • 你忘了在 .length 之后添加 () :)
  • 如果您只是在寻找 [ 字符,那么在正则表达式上进行拆分就太过分了。请改用indexOf('[')。更快、更清晰地表达意图。
【解决方案2】:

如果您想自己解析字符串,请使用正则表达式提取值。

不要使用正则表达式来查找要分割的字符,split() 就是这样做的。

相反,使用带有捕获组的正则表达式,使用Pattern.compile() 编译它,使用matcher() 在您的输入文本上获得Matcher,然后使用matches() 进行检查。

如果匹配,您可以使用group() 获取捕获的组。

示例正则表达式:

(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d+)[-+]\d{2}:\d{2}\[([^\]]+)\]

在 Java 字符串中,您必须对 \ 进行转义,所以下面的代码展示了它的工作原理:

String input = "2016-09-28T17:38:38.990-06:00[US/Mountain]";

String regex = "(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}).(\\d+)[-+]\\d{2}:\\d{2}\\[([^\\]]+)\\]";
Matcher m = Pattern.compile(regex).matcher(input);
if (m.matches()) {
    System.out.println("Year    : " + m.group(1));
    System.out.println("Month   : " + m.group(2));
    System.out.println("Day     : " + m.group(3));
    System.out.println("Hour    : " + m.group(4));
    System.out.println("Minute  : " + m.group(5));
    System.out.println("Second  : " + m.group(6));
    System.out.println("Fraction: " + m.group(7));
    System.out.println("TimeZone: " + m.group(8));
} else {
    System.out.println("** BAD INPUT **");
}

输出

Year    : 2016
Month   : 09
Day     : 28
Hour    : 17
Minute  : 38
Second  : 38
Fraction: 990
TimeZone: US/Mountain

更新

您当然可以使用ZonedDateTime.parse() 获得所有相同的值,这也将确保日期是有效,这是其他解决方案都无法做到的。

String input = "2016-09-28T17:38:38.990-06:00[US/Mountain]";

ZonedDateTime zdt = ZonedDateTime.parse(input);
System.out.println("Year    : " + zdt.getYear());
System.out.println("Month   : " + zdt.getMonthValue());
System.out.println("Day     : " + zdt.getDayOfMonth());
System.out.println("Hour    : " + zdt.getHour());
System.out.println("Minute  : " + zdt.getMinute());
System.out.println("Second  : " + zdt.getSecond());
System.out.println("Milli   : " + zdt.getNano() / 1000000);
System.out.println("TimeZone: " + zdt.getZone());

输出

Year    : 2016
Month   : 9
Day     : 28
Hour    : 17
Minute  : 38
Second  : 38
Milli   : 990
TimeZone: US/Mountain

【讨论】:

  • 感谢 ZonedDateTime.parse() 示例,我找不到合适的。
  • 可能没有这方面的例子,因为您可以通过查看ZonedDateTimedocumentation 轻松找到信息。
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
相关资源
最近更新 更多