Java: поиск элегантного способа разделения строки - PullRequest
0 голосов
/ 17 июня 2019

Я знаю, что есть много вопросов и ответов на темы, связанные с регулярными выражениями, и я уже прочитал многие из них и попробовал несколько способов сам, но все они не кажутся легкими для понимания.Поэтому я хотел спросить, может ли кто-нибудь помочь мне сделать это лучше?

Моя проблема

Я получаю строку, которая выглядит следующим образом (это строка в немецком формате):

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

Как видите, различные столбцы разделены точкой с запятой ;, но, к сожалению, символы точки с запятой также допускаются в полях комментариев (например, \;Andere Bemerkung) и, следовательно, экранируются (с \ источником)система, из которой я получаю строку.

Моя задача теперь состоит в том, чтобы проверить правильность числа столбцов в этой строке, но не изменять саму строку. В этом случае количество столбцов должно быть 5

Мое текущее решение

Поскольку я не очень хорошо разбираюсь в регулярных выражениях, и у меня мало времени, чтобы стать экспертом в решении этой проблемы, я использую различные API Java для разделенияСтрока:

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

Я использую API replace, потому что он не принимает выражение регулярного выражения, а просто String в качестве аргумента, и поэтому я могу заменить \; пробеломи затем успешно разделить строку на столбцы, и я могу проверить результат.Поскольку строки являются неизменяемыми, они работают нормально, но решение выглядит так, как будто в Java наверняка есть лучшие способы сделать это.

Я также искал в apache-commons-lang и API apache-commons-text , а также в предоставленных API spring-boot , но не смог найти лучшего решения.

Я также попробовал использовать регулярное выражение счерный список выражений, потому что в моем случае этот черный список был бы очень коротким, но, к сожалению, я думаю, что я даже не был близок к решению.

У вас есть какое-нибудь лучшее решение?

1 Ответ

2 голосов
/ 17 июня 2019

Прежде всего, если вы не избежите обратной косой черты, или в строке не может быть буквальных обратных косых черт, вы можете разделить ее ;, которому не предшествует \:

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

Если могут быть какие-либо экранированные объекты, используйте

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

regex для match обязательные поля.Смотрите это демонстрационное выражение .(?:[^;\\]|\\.)++ будет соответствовать 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, ]]
...