json 正则表达式捕获空字符串沿着预期的组,希望它不捕获空字符串

dm7nw8vv  于 2023-08-08  发布在  其他
关注(0)|答案(4)|浏览(100)

我构建了一个正则表达式来捕获模式中的值,其中模式用于识别json并从中获取值。但是除了预期的组之外,它还捕获组中的空字符串。
正则表达式:(?<=((?i)(finInstKey)":)["]?)(.*?)(?=["|,|}])|(?<="((?i)finInstKey","value":)["]?)(.*?)(?=["|,|}])
输入:
1.{“finInstKey”:500},{“name”:“finInstKey”,“value”:12345678900987654321}
1.{finInstKey”:“500”},{“name”:“finInstKey”,“value”:“12345678900987654321”}
对于这些输入,输入2还捕获空字符串沿着期望值。
实际输出:

500
12345678900987654321

500

12345678900987654321

字符串
预期产出:

500
12345678900987654321
500
12345678900987654321


到目前为止,我已经在Java代码中手动处理了它,但是如果regex不捕获空字符串就更好了。我应该在正则表达式中做什么修改才能得到预期的输出。

主要是,我想用这个替换掩码值为“****"的所有组。

我的代码:

public class RegexTester {
    private static final String regex = "(?<=((?i)(%s)\":)[\"]?)(.*?)(?=[\"|,|}])|(?<=\"((?i)%s\",\"value\":)[\"]?)(.*?)(?=[\"|,|}])";

    public static void main(String[] args) {
        String field = "finInstKey";
        String input = "{\"finInstKey\":500},{\"name\":\"finInstKey\",\"value\":12345678900987654321}{finInstKey\":\"500\"},{\"name\":\"finInstKey\",\"value\":\"12345678900987654321\"}";
        try {
            Pattern pattern = Pattern.compile(String.format(regex, field, field));
            Matcher matcher = pattern.matcher(input);
//            System.out.println(matcher.replaceAll("****"));
            while (matcher.find()) {
                System.out.println(matcher.group());
            }
        } catch (Exception e) {
            System.err.println(e);
        }

    }

}

qyzbxkaa

qyzbxkaa1#

使用JSON解析库来解析JSON可能比使用正则表达式更容易。从https://github.com/google/gson尝试.fromJSON方法
如果你坚持使用正则表达式,也许可以看看正则表达式中的+符号,它的意思是“匹配一个或多个”。当正则表达式变得像你所做的那样复杂时,它是很难阅读的。

u3r8eeie

u3r8eeie2#

您可以使用以下模式。捕获组为2和3。
考虑到文本值可能包含任何可能的分隔符,确定值的结尾并不容易。
确保您的数据符合要求;这意味着它只是一系列的数字。

(?si)(\"finInstKey\")\s*:\s*\"?(.+?)\b.+?\"name\"\s*:\s*\1\s*,\s*\"value\"\s*:\s*\"?(.+?)\b

字符串
尽管如此,我还是建议只使用一个 JSON 解析模块,* Gson * by Google 工作得很好。
你的 JSON 字符串实际上是数组,所以只需将每个字符串放在方括号内。

[
  {
    "finInstKey": 500
  },
  {
    "name": "finInstKey",
    "value": 12345678900987654321
  }
]


请注意,第二个示例中的 finInstKey 键缺少引号。

[
  {
    "finInstKey": "500"
  },
  {
    "name": "finInstKey",
    "value": "12345678900987654321"
  }
]


使用 Gson,您可以利用 JsonParser 类来解析 values

String stringA = "[\n" +
    "  {\n" +
    "    \"finInstKey\": 500\n" +
    "  },\n" +
    "  {\n" +
    "    \"name\": \"finInstKey\",\n" +
    "    \"value\": 12345678900987654321\n" +
    "  }\n" +
    "]";
String stringB = "[\n" +
    "  {\n" +
    "    \"finInstKey\": \"500\"\n" +
    "  },\n" +
    "  {\n" +
    "    \"name\": \"finInstKey\",\n" +
    "    \"value\": \"12345678900987654321\"\n" +
    "  }\n" +
    "]";

JsonArray arrayA = JsonParser.parseString(stringA).getAsJsonArray();
JsonObject objectA1 = arrayA.get(0).getAsJsonObject();
JsonElement elementA1 = objectA1.get("finInstKey");
int finInstKeyA = elementA1.getAsInt();
JsonObject objectA2 = arrayA.get(1).getAsJsonObject();
JsonElement elementA2 = objectA2.get("value");
BigInteger valueA = elementA2.getAsBigInteger();
System.out.println("finInstKeyA = " + finInstKeyA);
System.out.println("valueA = " + valueA);

JsonArray arrayB = JsonParser.parseString(stringB).getAsJsonArray();
JsonObject objectB1 = arrayB.get(0).getAsJsonObject();
JsonElement elementB1 = objectB1.get("finInstKey");
String finInstKeyB = elementB1.getAsString();
JsonObject objectB2 = arrayB.get(1).getAsJsonObject();
JsonElement elementB2 = objectB2.get("value");
String valueB = elementB2.getAsString();
System.out.println("finInstKeyB = " + finInstKeyB);
System.out.println("valueB = " + valueB);


产出

finInstKeyA = 500
valueA = 12345678900987654321
finInstKeyB = 500
valueB = 12345678900987654321

tez616oj

tez616oj3#

finInstKey键没有用引号括起来,导致空匹配。通过将模式更改为"finInstKey",您将允许它匹配此输入并正确提取值。
用它就像

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        String field = "finInstKey";
        String regex = "\"?" + field + "\"?(\\s*:\\s*\"?([^\",}]*)\"?|\",\"value\"\\s*:\\s*\"?([^\",}]*)\"?)";

        String input = "{\"finInstKey\":500},{\"name\":\"finInstKey\",\"value\":12345678900987654321}{finInstKey:\"500\"},{\"name\":\"finInstKey\",\"value\":\"12345678900987654321\"}";

        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(input);

        while (matcher.find()) {
            if (matcher.group(2) != null) {
                System.out.println(matcher.group(2));
            } else {
                System.out.println(matcher.group(3));
            }
        }
    }
}

字符串
这里是code

yrwegjxp

yrwegjxp4#

我认为你使用了不正确的regexp。

public static List<String> getData(String str, String field) {
    String regex = "(?:\"?" + field + "\"?:\"?(\\d+)\"?)|(?:\"name\":\""
            + field + "\",\"value\":\"?(\\d+)\"?)";
    Matcher matcher = Pattern.compile(regex).matcher(str);
    List<String> data = new ArrayList<>();

    while (matcher.find()) {
        data.add(Optional.ofNullable(matcher.group(1))
                         .orElseGet(() -> matcher.group(2)));
    }

    return data;
}

字符串

  • 输出:*
500
12345678900987654321
500
12345678900987654321

  • P.S.*我认为用regexp解析json是一个战略上的坏主意。我建议你使用任何Json解析器(Jackson,Gson,…)

相关问题