Java: 寻找一种优雅的拆分字符串的方法

Java: Searching an elegant way to split String

我知道有很多与正则表达式相关的问题和答案,我已经阅读了很多并且自己尝试了几种方法,但它们似乎都不太容易理解。所以我想问问有没有人可以帮我做的更好?

我的问题

我得到一个看起来像这样的字符串(它是德语格式的字符串):

"[Header: 150,00;20.02.2019;Bemerkung\]\;;\;Andere Bemerkung;]"

如您所见,不同的列由分号分隔 ; 但不幸的是,分号字符也允许出现在注释字段中(例如 \;Andere Bemerkung),因此被转义(使用 \ 由我从中获取字符串的源系统提供。

我现在的任务是验证此字符串中的列数是否正确,但不更改字符串本身。在这种情况下,列数应为 5

我目前的解决方案

由于我不擅长正则表达式并且现在成为解决这个问题的专家的时间很短,所以我使用不同的 Java API 来拆分字符串:

"[Header: 150,00;20.02.2019;Bemerkung\]\;;\;Andere Bemerkung;]".replace("\;", " ").split(";")

我使用 replace API 因为它不接受正则表达式而只是 String 作为参数,所以我可以替换 \;使用空格,然后成功地将字符串拆分为列,我能够验证结果。因为字符串是不可变的,所以它工作正常,但解决方案看起来肯定有更好的方法 Java.

我还在 apache-commons-langapache-commons-text API 中搜索过提供了 spring-boot APIs,但找不到更好的解决方案。

我还尝试了一个带有表达式黑名单的正则表达式,因为在我的情况下这个黑名单会非常短,但不幸的是我认为我什至没有接近解决方案。

你有更好的解决方案吗?

首先,如果您不转义反斜杠,或者字符串中不能有任何文字反斜杠,您可以使用不以 \ 开头的 ;:

s.split("(?<!\\);")

如果可以有任何转义实体,使用

(?:[^;\]|\.)++

正则表达式 匹配 必填字段。参见 this regex demo(?:[^;\]|\.)++ 将匹配任何字符的 1 次或多次重复,但 ;\\ 后跟任何字符。如果要拆分的内容中可以有换行符,则使用 Pattern.DOTALL 标志编译模式。

Java demo:

String s = "[Header: 150,00;20.02.2019;Bemerkung\]\;;\;Andere Bemerkung;]";
List<String> result = new ArrayList<>();
Pattern pattern = Pattern.compile("(?:[^;\\]|\\.)++");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    result.add(matcher.group(0)); 
} 
System.out.println(result);
// => [[Header: 150,00, 20.02.2019, Bemerkung\]\;, \;Andere Bemerkung, ]]