Java:搜索分割字符串的优雅方法

时间:2019-06-17 14:11:17

标签: java regex spring-boot apache-commons

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

我的问题

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

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

如您所见,不同的列用分号;分隔,但不幸的是,注释字段中也允许使用分号字符(例如\;Andere Bemerkung),因此可以转义(用{{1 }}由我从中获取字符串的源系统进行。

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

我当前的解决方案

由于我对正则表达式不满意,并且现在成为解决此问题的专家的时间很短,因此我使用了不同的Java API来拆分String:

\

我使用"[Header: 150,00;20.02.2019;Bemerkung\\]\\;;\\;Andere Bemerkung;]".replace("\\;", " ").split(";") API是因为它不使用正则表达式,而只是使用replace作为参数,因此我可以用空格替换String,然后成功拆分将字符串放入列中,然后我就可以验证结果了。由于字符串是不可变的,因此可以很好地工作,但是该解决方案似乎肯定存在Java中更好的方法。

我还在 apache-commons-lang apache-commons-text API以及提供的 spring-boot API中进行了搜索,但找不到更好的解决方案。

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

您有更好的解决方案吗?

1 个答案:

答案 0 :(得分:2)

首先,如果您不转义反斜杠,或者字符串中没有任何文字反斜杠,则可以使用;进行拆分,而该\不能以s.split("(?<!\\\\);") 开头:

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

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

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

regex匹配 必填字段。参见this regex demo;将匹配1个或多个重复的任何字符,但\\Pattern.DOTALL后跟任何字符。如果要拆分的内容中可能存在换行符,请使用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, ]] 标志编译该模式。

Java demo

  client.beginRequest();
  client.post("/input");
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", postData.length());
  client.beginBody();
  client.println(postData);
  client.endRequest();