我知道正则表达式相关主题有很多问题和答案,我已经阅读了很多问题和答案,并自己尝试了几种方法,但它们似乎都不容易理解。所以我想问一下是否有人可以帮助我做得更好?
我的问题
我得到一个看起来像这样的字符串(它是一个德语格式的字符串):
"[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-lang和apache-commons-textAPI以及提供的spring-bootAPI中搜索,但找不到更好的解决方案。
我还尝试了一个带有表达式黑名单的正则表达式,因为在我的情况下,这个黑名单会很短,但不幸的是,我认为我什至没有接近解决方案。
您有更好的解决方案吗?
首先,如果你不转义反斜杠,或者字符串中不能有任何文字反斜杠,你可以用前面没有的
;
拆分:
s.split("(?<!\\);")
如果可以有任何转义的实体,请使用
(?:[^;\]|\.)++
正则表达式以匹配必填字段。请参阅此正则表达式演示。(?:[^;\]|\.)++
将匹配任何字符的 1 次或多次重复,但;
和或
后跟任何字符。如果内容中可以有要拆分的内容中有换行符,请使用
Pattern.DOTALL
标志编译模式。
Java演示:
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, ]]