Я использую 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