【问题标题】:Replace whitespace in JSON keys替换 JSON 键中的空格
【发布时间】:2015-05-14 02:32:18
【问题描述】:

我正在考虑用下划线替换 JSON 键中的所有空格的最佳解决方案。

{ 
  "Format": "JSON", 
  "TestData": { 
    "Key with Spaces in it": { 
      "And Again": { 
        "Child_Key1": "Financial", 
        "Child_Key2": null 
      }, 
......... 
..... 

我想把上面的转换成如下图:

{ 
  "Format": "JSON", 
  "TestData": { 
    "Key_with_Spaces_in_it": { 
      "And_Again": { 
        "Child_Key1": "Financial", 
        "Child_Key2": null 
      }, 
......... 
..... 

有什么建议吗?

是否有任何 Java 库有任何预定义的函数来执行此操作?

【问题讨论】:

标签: java json parsing


【解决方案1】:

更换密钥

以下代码使用 Google 的 JSON 解析器来提取密钥,重新格式化它们,然后创建一个新的 JSON 对象:

public static void main(String[] args) {
    String testJSON = "{\"TestKey\": \"TEST\", \"Test spaces\": { \"child spaces 1\": \"child value 1\", \"child spaces 2\": \"child value 2\" } }";
    Map oldJSONObject = new Gson().fromJson(testJSON, Map.class);
    JsonObject newJSONObject = iterateJSON(oldJSONObject);

    Gson someGson = new Gson();
    String outputJson = someGson.toJson(newJSONObject);
    System.out.println(outputJson);
}

private static JsonObject iterateJSON(Map JSONData) {
    JsonObject newJSONObject = new JsonObject();
    Set jsonKeys = JSONData.keySet();
    Iterator<?> keys = jsonKeys.iterator();
    while(keys.hasNext()) {
        String currentKey = (String) keys.next();
        String newKey = currentKey.replaceAll(" ", "_");
        if (JSONData.get(currentKey) instanceof Map) {
            JsonObject currentValue = iterateJSON((Map) JSONData.get(currentKey));
            newJSONObject.add(currentKey, currentValue);
        } else {
            String currentValue = (String) JSONData.get(currentKey);
            newJSONObject.addProperty(newKey, currentValue);
        }
    }
    return newJSONObject;
}

您可以阅读有关 GSON 的更多信息here

替换值

根据您的 JSON 数据的设置方式,您可能需要将 JSONArray 与 JSONObject 进行切换。

JSONArrays 以 [] 开头和结尾,而 JSONObjects 以 {} 开头和结尾

简而言之,这些方法将遍历整个数组/对象并将所有空格替换为下划线。它们是递归的,因此它们将深入到子 JSONArrays/JSONObjects。

如果 JSON 数据编码为 Java JSONArray,您可以执行以下操作:

public static void removeJSONSpaces(JSONArray theJSON) {
    for (int i = 0; while i < theJSON.length(); i++) {
        if (theJSON.get(i) instanceof JSONArray) {
            currentJSONArray = theJSON.getJSONArray(i);
            removeJSONSpaces(currentJSONArray);
        } else {
            currentEntry = theJSON.getString(i);
            fixedEntry = currentEntry.replace(" ", "_");
            currentJSONArray.put(i, fixedEntry);
        }
    }
}

简而言之,此方法将遍历整个数组并将所有空格替换为下划线。它是递归的,所以它会深入到子 JSONArrays。

您可以阅读更多关于 JSONArrays here

如果数据被编码为 JSONObject,您需要执行以下操作:

public static void removeJSONSpaces(JSONObject theJSON) {

    jObject = new JSONObject(theJSON.trim());
    Iterator<?> keys = jObject.keys();

    while(keys.hasNext()) {
        String key = (String)keys.next();
        if (jObject.get(key) instanceof JSONObject) {
            removeJSONSpaces(jObject.get(key))
        } else {
            currentEntry = theJSON.getString(i);
            fixedEntry = currentEntry.replace(" ", "_");
            currentJSONArray.put(i, fixedEntry);
        }
    }

}

您可以阅读更多关于 JSONObjects here

【讨论】:

  • 非常感谢您的回复,您的想法看起来不错。但是我想重命名密钥本身的名称, put() 如何重命名密钥?它不会成为一个价值吗?我在这里有点困惑。
  • 另外这只会替换极端子键,而不是所有键:(
  • 伙计,还有更多的 cmets 吗?您的想法可能会在这里引发更好的解决方案:)
  • 你好,正如我提到的那样,这不是确切的解决方案。但是我已经调整了您的解决方案,但是。在键和值中,我用 SP 替换空格,用 SYMBOL_KEYWORD 替换符号。然后就解决了我的问题。因为我有一个外部响应映射要做,所以我使用 xslt 将其替换为实际值,例如 SP 与 ' '
  • gson 2.8.2 中的类型名称略有变化 - JSONArray 现在是 JsonArray & JSONObject 现在是 JsonObject
【解决方案2】:

您可以只读取每个键/值,然后使用String replace(String oldString, String newString) 方法。

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)

【讨论】:

    【解决方案3】:

    试试这个:

          String testJSON = "{\"menu\": {\n" +
            "  \"id no\": \"file\",\n" +
            "  \"value type\": \"File\",\n" +
            "  \"popup value\": {\n" +
            "    \"menu item\": [\n" +
            "      {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},\n" +
            "      {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},\n" +
            "      {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}\n" +
            "    ]\n" +
            "  }\n" +
            "}}";
                 JSONObject json = new JSONObject(testJSON);
                 System.out.println("Final output: "+replaceKeyWhiteSpace(json));
    

    用“_”替换空格

    private static JSONObject replaceKeyWhiteSpace(Object json) {
    JSONObject jsonObject = null;
    if (json instanceof JSONObject) {
        jsonObject = (JSONObject) json;
        List<String> keyList = new LinkedList<String>(jsonObject.keySet());
        for (String key : keyList) {
            if (!key.matches(".*[\\s\t\n]+.*")) {
                Object value = jsonObject.get(key);
                replaceKeyWhiteSpace(value);
                continue;
            }
    
            Object value = jsonObject.remove(key);
            String newKey = key.replaceAll("[\\s\t\n]", "_");
    
            replaceKeyWhiteSpace(value);
    
            jsonObject.accumulate(newKey, value);
    
        }
    } else if (json instanceof JSONArray) {
        for (Object aJsonArray : (JSONArray) json) {
            replaceKeyWhiteSpace(aJsonArray);
        }
    }
    return jsonObject;
    

    }

    【讨论】:

      【解决方案4】:

      我正在使用 gson 库从 json 字符串中删除坏键,因为我想创建 json 的 AVRO 文件。 Avro 不接受带有空格或非字母数字的键,因此我必须先清理输入。

      上面的 sn-p 从所有键中删除空格和字符 $(迭代)。我假设我的 json 字符串是 JsonObject。

      查看我使用过的一个小示例代码。

      for (String json: allJsons){
              JsonObject schema = new JsonParser().parse(json).getAsJsonObject();
              JsonObject cleanSchema = new JsonObject();
              Set<Map.Entry<String, JsonElement>> entries = schema.entrySet();
              for (Map.Entry<String, JsonElement> entry: entries) {
                  String key = entry.getKey().replace("$","").replace(" ","");
                  JsonElement value = entry.getValue();
                  if (value.isJsonObject()){
                      JsonObject subValue = new JsonObject();
                      Set <Map.Entry<String, JsonElement>> subEntries = ((JsonObject) value).entrySet();
                      for (Map.Entry<String, JsonElement> subEntry: subEntries) {
                          String subKey = subEntry.getKey().replace("$","").replace(" ","");
                          subValue.add(subKey, subEntry.getValue());
                      }
                      value = subValue;
                  }
                  cleanSchema.add(key, value);
              }
      
              System.out.println("Clean schema "+cleanSchema.toString());
              byte[] bytes = converter.convertToAvro(cleanSchema.toString().getBytes(), avroSchema);
              String avroFile = outputFileName+"_"+counter+".avsc";
              Files.write(Paths.get(avroFile), bytes);
              counter++;
              System.out.println("Avro File Created "+avroFile);
          }
      

      【讨论】:

        【解决方案5】:

        这就是我从 Json Keys 中删除空格的方法。解决方案适用于 JsonArray 和 JsonObject,只需使用空格打印匹配的正则表达式键并替换这些键。 现场演示:online Java compiler

        import java.util.regex.Pattern;
        import java.util.regex.Matcher;
        
        public class MatcherGroupExample {
        
            public static void main(String[] args) {
        
                String text   = "{\"co nf ig\": {\"oauthSecret\": [{\"i d\": 45,\"config123\": {\"oauthSecret\": \"P8n2x5Ht0nFRRB0A\",\"status\": \"CREATED\"},\"SERVER132\": \"1000\"},{\"id\": 46,\"config123\": {\"oauthSecret\": \"wP8n2x5Ht0nFRRB0A\",\"status\": \"CREATED\"},\"SERVER132\": \"1000\"}],\"oauthKey\": \"newtest\",\"SERV ER\": \"1000\"},\"feat ures\": [ 9004, 9005] ,\"d\":\"dd\"}";
        
        
                String patternString1 = "\"([^\"]+?[ ]+[^\"]+?)\"\\s*:";
        
                Pattern pattern = Pattern.compile(patternString1);
                Matcher matcher = pattern.matcher(text);
        
                while(matcher.find()) {
                    System.out.println("found: " + matcher.group(1));
                   text= text.replaceAll("\""+matcher.group(1)+"\"","\""+(matcher.group(1).replaceAll(" ",""))+"\"");
        
                }
                 System.out.println("Final output:"+text);
            }
        }
        

        【讨论】:

        • 如何使用此代码修剪 json 值
        【解决方案6】:

        仅删除 jason 代码中字符串上的空格,而不是 jason 代码中的所有空格

        public String removeWhiwspaceInJasonString(String jsonStr) {
            boolean changeActive = false;
            String output = '';
            for(int i=0; i<jsonStr; i++){
        
                if(jsonStr.charAt(i) == '"')
                    changeActive  =!changeActive;
                else if(changeActive)
                  if(jsonStr.charAt(i) == ' ')
                     output += '_';
                  else
                     output += jsonStr.charAt(i);
                else
                  output += jsonStr.charAt(i);
        
            }
            return output;
        }
        

        【讨论】:

        • 强烈建议不要使用手动字符串或常规表达式操作来处理 JSON 字符串。由于规范,有许多数据、函数格式以及转义字符规则。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-25
        相关资源
        最近更新 更多