不匹配带有“String.split”的两个字符序列之间的正则表达式
Not match Regex in between two character sequences with `String.split`
我正在使用 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
之后的逗号 space 和 US
之后的逗号,并忽略 Boston
之后的逗号。幸运的是,我可以相信这些发生在 url=
和 , is_test=
之间的坏情况(仅此而已)。我一直在用 Java 正则表达式测试器敲打这里:https://www.freeformatter.com/java-regex-tester.html 但失败了。我可以通过上述输入得到的最接近的是:
(?<!url=[.]{0,300}^, is_test), (?!.*, is_test)
,只匹配US
后的逗号-space,而不匹配bar
后的逗号-space。 {0,300}
用于缓解 Java 正则表达式无法处理潜在的无限后视表达式的问题:
java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length
我该如何解决这个问题?理想情况下,我可以或用引号逗号 space 忽略一个的表达式。一种可能性也是在 url=
和 , is_test
之间匹配 </code> 并将它们替换为 <code>%20
。不幸的是,在那个 Regex 表达式中,我得到的最接近的是 (?<=url=.{0,300})\s(?!^\w*, is_test)
,它与我不想触摸的 is_test
之前的白色 space 相匹配。
==编辑==
我的第一个示例没有包含带有 =
的查询字符串,这是我的问题的主要部分。这是我正在处理的更完整的示例:
foo="bar, harbor", url=http://city.com/start_city=Boston, MA US&end_city=New York, NY US, is_test=false
由于您的键值对由 =
分隔,并且您的每个键值对由一个逗号和一些 space 分隔,您可以在 [= 之前的每个逗号上拆分13=] 使用此正则表达式的字符,
,\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
让我知道这是否适用于您的情况,如果不适用,请添加它不适用的情况。
我正在使用 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
之后的逗号 space 和 US
之后的逗号,并忽略 Boston
之后的逗号。幸运的是,我可以相信这些发生在 url=
和 , is_test=
之间的坏情况(仅此而已)。我一直在用 Java 正则表达式测试器敲打这里:https://www.freeformatter.com/java-regex-tester.html 但失败了。我可以通过上述输入得到的最接近的是:
(?<!url=[.]{0,300}^, is_test), (?!.*, is_test)
,只匹配US
后的逗号-space,而不匹配bar
后的逗号-space。 {0,300}
用于缓解 Java 正则表达式无法处理潜在的无限后视表达式的问题:
java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length
我该如何解决这个问题?理想情况下,我可以或用引号逗号 space 忽略一个的表达式。一种可能性也是在 url=
和 , is_test
之间匹配 </code> 并将它们替换为 <code>%20
。不幸的是,在那个 Regex 表达式中,我得到的最接近的是 (?<=url=.{0,300})\s(?!^\w*, is_test)
,它与我不想触摸的 is_test
之前的白色 space 相匹配。
==编辑==
我的第一个示例没有包含带有 =
的查询字符串,这是我的问题的主要部分。这是我正在处理的更完整的示例:
foo="bar, harbor", url=http://city.com/start_city=Boston, MA US&end_city=New York, NY US, is_test=false
由于您的键值对由 =
分隔,并且您的每个键值对由一个逗号和一些 space 分隔,您可以在 [= 之前的每个逗号上拆分13=] 使用此正则表达式的字符,
,\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
让我知道这是否适用于您的情况,如果不适用,请添加它不适用的情况。