Не соответствует Regex между двумя последовательностями символов с `String.split` - PullRequest
1 голос
/ 13 марта 2019

Я использую Scala для работы с очень запутанными данными, которые нецелесообразно очищать.Он поставляется в виде пар ключей-значений с разделителями, что-то вроде этого: "a=1, b=2, c=3".Я использую String.split, чтобы разбить строку на пары ключ-значение.Большинство частей строковых значений этих пар заключаются в кавычки, если это необходимо, поэтому это работает, чтобы не соответствовать , внутри кавычек: <string-instance>.split(", (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")

Однако я натолкнулся на поле urlэто ни в кавычках, ни во всех случаях кодируется URL, поэтому мне приходится иметь дело с чем-то вроде этого:

"foo=bar, url=http://city.com/Boston, MA US, is_test=false"

В этом случае я пытаюсь найти запятуюпробел после bar и после US и игнорируйте один после Boston.К счастью, я могу положиться на эти плохие случаи, попадающие между url= и , is_test= везде, где они происходят (и это все).Я бился головой о тестере Java regex здесь: https://www.freeformatter.com/java-regex-tester.html и терпел неудачу.Самое близкое, что я мог получить с вышеупомянутым вводом, было это: (?<!url=[.]{0,300}^, is_test), (?!.*, is_test), который соответствовал запятой после US, а не после bar.{0,300} существует для того, чтобы облегчить проблему Java Regex, неспособного обрабатывать потенциально бесконечные косвенные выражения: java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length

Как я могу решить эту проблему?В идеале я мог бы или выражение с кавычками, игнорируя один.Одной из возможностей также может быть совпадение между url= и , is_test и замена их на %20.К сожалению, в этом выражении Regex самое близкое, что я получил, было (?<=url=.{0,300})\s(?!^\w*, is_test), которое соответствовало пробелу прямо перед is_test, которого я не хочу касаться.

== edit ==

Мой первый пример не включал строку запроса с =, которая является основной частью моей проблемы.Вот более полный пример того, с чем я имею дело:

foo="bar, harbor", url=http://city.com/start_city=Boston, MA US&end_city=New York, NY US, is_test=false

1 Ответ

2 голосов
/ 13 марта 2019

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

,\s*(?=\w+=)

Демонстрация онлайн

Проверьте эти Java-коды, которые разбивают вашу строку в нужных позициях,

String[] data = "foo=\"bar, harbor\", url=http://city.com/start_city=Boston, MAUS&end_city=New York, NY US, is_test=false".split(",\\s*(?=\\w+=)");
Arrays.stream(data).forEach(System.out::println);

печать

foo="bar, harbor"
url=http://city.com/start_city=Boston, MAUS&end_city=New York, NY US
is_test=false

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

...