替换JSON键中的空格

3

我在思考一种最佳方案,用下划线替换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库具有预定义的函数来执行此操作?


如果涉及将JSON解析为对象,最好的方法是使用@JsonProperty("Key with Spaces in it")。请参阅https://github.com/FasterXML/jackson-annotations获取更多详细信息。 - wittich
6个回答

8

替换键

以下代码使用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的更多信息:这里替换值 根据您的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的内容。
如果数据编码为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的更多信息。

非常感谢您的回复,您的想法看起来不错。但是我想要重新命名键本身的名称,使用put()方法可以重命名键吗?它不会变成一个值吗?我有点困惑。 - gnanagurus
同时,这将仅替换极端子键,而不是所有的键 :( - gnanagurus
大哥,对这个有什么更多的评论吗?你的想法可能会引发一个更好的解决方案啊 :) - gnanagurus
嗨,正如我之前提到的,put并不是确切的解决方案。但是我稍微修改了你的解决方案。在键和值中,我用 SP 替换空格,用 SYMBOL_KEYWORD 替换符号。这样解决了我的问题。由于我需要进行外部响应映射,所以我使用 xslt 将其替换为实际值,例如将 SP 替换为 ' '。 - gnanagurus
1
gson 2.8.2中,类型名称略有变化 - JSONArray现在是JsonArray,而JSONObject现在是JsonObject - Stuart Cardall

1

1

Try this one:

      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;

}


0

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

上面的代码片段会迭代地删除所有键中的空格和字符$。我假设我的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);
    }

0

这是我用来删除Json键中的空格的方法。该解决方案适用于JsonArray和JsonObject,只需打印匹配正则表达式键并替换这些键中的空格。 在线演示:在线Java编译器

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值进行修剪? - Chennai Cheetah

-2

仅删除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;
}

1
强烈不建议使用手动字符串或正则表达式操作来处理JSON字符串。由于规范的原因,有许多数据、函数格式以及转义字符规则。 - hsnkhrmn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接