Java正则表达式-如何应用正则表达式来获取由ASCII字符括起的所有字符串?

Java正则表达式-如何应用正则表达式来获取由ASCII字符括起的所有字符串?,java,regex,Java,Regex,我得到了一个包含ASCII{,}和的文本字符串。我试图提取它们所包含的所有字符串。我知道我是个新手,我的代码中可能有十几个错误,所以请容忍我 ASCII格式: { = %5B } = %5D " = %22 Java字符串如下所示: "%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D," 我使用的正则表达式模式是: "%22(.*)%22:%5B(.*)%5D" 我在下面编写了以下代码,但输出似乎不起作用。正确的方法是什么 代码: Strin

我得到了一个包含ASCII{,}和的文本字符串。我试图提取它们所包含的所有字符串。我知道我是个新手,我的代码中可能有十几个错误,所以请容忍我

ASCII格式:

{ = %5B
} = %5D
" = %22
Java字符串如下所示:

"%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D,"
我使用的正则表达式模式是:

"%22(.*)%22:%5B(.*)%5D"
我在下面编写了以下代码,但输出似乎不起作用。正确的方法是什么

代码:

String line = "%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D,";
Matcher m = Pattern.compile("%22(.*)%22:%5B(.*)%5D").matcher(line);
while (m.find()) {
    for (int i = 0; i < m.groupCount(); i++) {
        System.out.print(m.group(i)+" ");
    }
    System.out.println();
}
实际产量:

%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D key1%22:%5Bvalue1%5D, %22key2 
您的字符串似乎包含URL编码的值。我会先用,然后用

String str = "%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D,";
try {
    str = URLDecoder.decode(str, "UTF-8");
    String[] kvParts = str.split(",\\s*");
    for (String parts : kvParts) {
        String[] arr = parts.split(":");
        String key = arr[0].substring(1, arr[0].length() - 1);
        String value = arr[1].substring(1, arr[1].length() - 1);
        System.out.printf("%s %s%n", key, value);
    }
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
输出符合要求

key1 value1
key2 value2

根据javadoc,默认情况下捕获组0是整个字符串。它不包括在groupCount中。因此,只要稍加修改,您就可以真正得到您想要的:


还请注意不情愿限定符的用法?在组中,这会阻止匹配器搜索字符串中的最后一个分隔符。

这里有一行代码供您使用:

String input = "%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D,";

Map<String, String> map = Arrays.stream(input.replaceAll("%..", "").split(", ?"))
.map(s -> s.split(" ?: ?"))
.collect(Collectors.toMap(a -> a[0], a -> a[1]));

System.out.println(map);

默认情况下,regex是贪婪的。这意味着如果你有一个字符串AAAAA,那么正则表达式a*a将匹配整个字符串,而不仅仅是第一个a,因为Kleene星将匹配尽可能多的字符

在您的情况下,您需要lazy regex。你可以用*?或+?。因此,您的表达式将如下所示:

%22(.*?)%22:%5B(.*?)%5D
String input = "%22key1%22:%5Bvalue1%5D, %22key2%22:%5Bvalue2%5D,";

Map<String, String> map = Arrays.stream(input.replaceAll("%..", "").split(", ?"))
.map(s -> s.split(" ?: ?"))
.collect(Collectors.toMap(a -> a[0], a -> a[1]));

System.out.println(map);
{key1=value1, key2=value2}
%22(.*?)%22:%5B(.*?)%5D