【问题标题】:Regex gives only one match [closed]正则表达式只给出一个匹配[关闭]
【发布时间】:2020-07-12 22:00:53
【问题描述】:

我正在尝试编写代码以按照某种模式从字符串中提取一些值。基本上是来自 json 的键和值,其中值包含在 {{value}}

在下面的代码中:

String jsonString = "{\"title\":\"{{string_64|dsm_title}}\",\"code\":\"{{string_16|dsm_code}}\",\"enabled\":true,\"enableAdvanceFilter\":false,\"deleteAfterScheduledTime\":false,\"enableDataStoreLog\":false}";
        String patternString = "[\"](?<key>.*)[\"][:][? ]?.*[{][{](?<value>.*)[}][}]";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(jsonString);
        HashMap<String, Object> allMatches = new HashMap<>();
        while (matcher.find()) {
            allMatches.put(matcher.group("value"), matcher.group("key"));
        }
        System.out.println(allMatches);

我期望输出为:

string_64|dsm_title -> title
string_16|dsm_code -> code

但它给我的输出是:

string_16|dsm_code -> title":"{{string_64|dsm_title}}","code

请帮助我纠正正则表达式。 请不要提供有关将其解析为 json 和所有内容的解决方案。这不是我需要的解决方案。

【问题讨论】:

  • 不要使用正则表达式解析 JSON。使用 JSON 解析器。
  • 我没有解析 json。我正在尝试按照某种模式提取一些字符串。不要将其视为 json。将其视为一个简单的字符串。
  • 从值映射到键是一个非常奇怪的想法。这意味着如果两个键具有相同的值,则结果映射中只有一个。

标签: java regex


【解决方案1】:

由于这是您正在使用的 JSON,您应该真正使用 JSON 解析器将您的 JSON 字符串转换为对象或映射,这些解析器内置了将 JSON 字符串转换为映射的函数 - 很好的例子是GSON 和 Java 自己的 JSON 解析器。现在,正如人们常说的那样,您正在“重新发明轮子”,通过编写其他人已经编写的代码来增加复杂性,这可能比 RegEx 方法更有效。了解如何使用 Jackson here 之类的东西从 JSONObject 转到地图

但是,如果您真的想在这个问题上使用 RegEx,我会使用类似于此的 RegEx:(?&gt;\\\")(?&lt;key&gt;.*?)(?&gt;\\\":\\\"\\{\\{)(?&lt;value&gt;.*?)(?&gt;\\}\\}\\\")。您可以看到它与您的代码 here 一起使用。这将为您提供输出 {string_64|dsm_title=title, string_16|dsm_code=code},因为您在示例中直接打印地图。

如果指向 sn-p 的链接对您不起作用,请直接在给定代码代码中进行更改:

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

class Main {
  public static void main(String[] args) {
    String jsonString = "{\"title\":\"{{string_64|dsm_title}}\",\"code\":\"{{string_16|dsm_code}}\",\"enabled\":true,\"enableAdvanceFilter\":false,\"deleteAfterScheduledTime\":false,\"enableDataStoreLog\":false}";
    String patternString = "(?>\\\")(?<key>.*?)(?>\\\":\\\"\\{\\{)(?<value>.*?)(?>\\}\\}\\\")";

    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(jsonString);

    HashMap<String, Object> allMatches = new HashMap<>();
    while (matcher.find()) {
      allMatches.put(matcher.group("value"), matcher.group("key"));
    }

    System.out.println(allMatches);
  }
}

还有一种让我感到困惑的是,您在 RegEx 中命名为“键”的部分随后使用,value 在您的地图中,以及您在 RegEx 中命名为“值”的部分您用作地图的。您可能需要重新考虑您的命名约定和方法,因为这可能会使将来的人们更难阅读您的代码。

【讨论】:

  • 感谢您的帮助。是的,我肯定会更改键和值的命名约定
猜你喜欢
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多