【问题标题】:Return first/second occurrence返回第一次/第二次出现
【发布时间】:2021-12-28 22:40:21
【问题描述】:

我正在寻找一种方法来抓取/捕获 {"$oid": 旁边的第二次出现的数字(仅数字):

我能够捕捉到第一个但无法捕捉到第二/第三次出现。

这是我使用的正则表达式: https://regex101.com/r/6cSXi8/1

"(?<="\$oid": ").*?[^"},]*"

输入示例:

[{"_id": {"$oid": "5f9ecf8ca9bec5549493ba7d"}, "policy_name": "aaa", "is_mobile": false,, {"_id": {"$oid": "6090fead53bc363849fce989"}, "policy_name": "bbb", "is_mobile": true, {"_id": {"$oid": "619cf729ea016d1e3336e903"}, "policy_name": "ccc", "is_mobile": false}]

此外,我还试图弄清楚如何匹配 "is_mobile" : true 到第二次出现的数字。表示将通过搜索“is_mobile”返回第二个数字(在 {"$oid":) 旁边的正则表达式:true

我正在使用 Java 发送正则表达式

非常感谢您的帮助。

【问题讨论】:

  • 使用正则表达式解析 JSON 最终会失败。你真的应该使用合适的 JSON 解析器。

标签: java regex


【解决方案1】:

您说您使用 Java,所以您必须在 regex101 中选择“Java”!这将告诉您转义所有双引号 (")。

我已将您的正则表达式更改为使用“Global”标志并更改了前瞻:

"(?<=\"\$oid\": \")[^\"]+(?=\"[^$]+\"is_mobile\": true)"

后面的样子是一样的。然后我更改了匹配以匹配任何不是双引号 " 的字符。

然后我添加一个前瞻来寻找:

" 结束匹配的双引号

[^$]+ 任何不属于$ 的字符(一个或多个) - 这可确保向前看不会向前看另一项(可能具有真实值),而是保留在同一项中。

\"is_mobile\": true 向前看 true 值。

Global”仅在其后跟 ìs_mobile: true 时才会匹配所有出现。

【讨论】:

  • 感谢您的解释。如何在不使用“is_mobile”的情况下获得第二个号码:true?我想获得第三次(第 n 次)。
  • 如果您想要所有匹配项,只需设置 global 标志,无需向前看。
  • 您能否提供一个使用正则表达式链接的正则表达式示例,我提供的链接仅用于获取第二个数字?
  • 我上面答案中的正则表达式只给你第二个数字。您必须使用全局标志。
【解决方案2】:

其他选择:

在上下文和测试平台中查看正则表达式:

public static void main(String[] args) {
    String input = "[{\"_id\": {\"$oid\": \"5f9ecf8ca9bec5549493ba7d\"}, " +
            "\"policy_name\": \"aaa\", \"is_mobile\": false," +
            ", {\"_id\": {\"$oid\": \"6090fead53bc363849fce989\"}, " +
            "\"policy_name\": \"bbb\", \"is_mobile\": true, " +
            "{\"_id\": {\"$oid\": \"619cf729ea016d1e3336e903\"}, " +
            "\"policy_name\": \"ccc\", \"is_mobile\": false}]";

    Pattern pattern = Pattern.compile("\"\\$oid\":\\s+\"(\\S+)\".*?\"is_mobile\":\\s+(true|false)");
    Matcher matcher = pattern.matcher(input);

    //Alternative 1:
    System.out.println("Alternative 1:");
    while(matcher.find()) {
        if(matcher.group(2).equals("true")) {
            System.out.println(matcher.group(1));
        }
    }

    //Alternative 2:
    Pattern pattern2 = Pattern.compile("\"\\$oid\":\\s\"(\\S+)\".*is_mobile\":\\s(true|false)");
    List<String> isMobileTrueOidList = Arrays.asList(input.split("(?<=is_mobile\":\\s(true|false))")).stream()
            .map(pattern2::matcher)
            .filter(Matcher::find)
            .filter(matcher2 -> matcher2.group(2).equals("true"))
            .map(matcher2 -> matcher2.group(1))
            .collect(Collectors.toList());

    System.out.println("\nAlternative 2:");
    isMobileTrueOidList.forEach(System.out::println);
}

输出:

Alternative 1:
6090fead53bc363849fce989

Alternative 2:
6090fead53bc363849fce989

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多