我正在使用Scala处理一些非常凌乱的数据,这些数据很难清理。它采用带分隔符的键/值对的形式,例如:"a=1, b=2, c=3"
。我正在使用String.split
将String分解为键值对。如果需要,这些对的大多数字符串值部分都用引号引起来,因此这可以使引号,
内的<string-instance>.split(", (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")
不匹配
但是,我遇到了一个url
字段,该字段既不加引号,也不在所有情况下都进行URL编码,因此我必须处理类似这样的事情:
"foo=bar, url=http://city.com/Boston, MA US, is_test=false"
在这种情况下,我试图匹配bar
之后的逗号和US
之后的逗号,并忽略Boston
之后的逗号。幸运的是,我可以依靠发生在url=
和, is_test=
之间的这些坏情况(仅此而已)。我在https://www.freeformatter.com/java-regex-tester.html上用Java regex测试器敲了敲头,但失败了。通过上面的输入我能得到的最接近的是:
(?<!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
答案 0 :(得分:2)
由于键值对之间用=
隔开,并且每个键对之间都用逗号和空格隔开,因此您可以使用{正则表达式,
=
检查这些Java代码,这些代码会将您的字符串分割到所需位置,
,\s*(?=\w+=)
打印
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);
让我知道这是否适用于您的情况,如果不能,请添加不适用于您的情况。