2017-06-23 66 views
0

我的字符串输入是一样的东西:通过正则表达式替换字符串的一部分

{"key1":"value1","key2":"{\"key2_1\":\"123\",\"key2_2\":\"456\",\"key2_3\":\"33333\"}"} 

在上面的JSON值的字段可以包含如"\等字符。为了您的方便易用这里是格式化版本:

{ 
    "key1": "value1", 
    "key2": "{\"key2_1\":\"123\",\"key2_2\":\"456\",\"key2_3\":\"33333\"}" 
} 

我想用GSON到字符串转换为Foo对象:

class Foo { 
    private String key1; 
    private Bar key2; 
    ... 
} 

class Bar { 
    private String key2_1; 
    private String key2_2; 
    private String key2_3; 
    ... 
} 

这里是我的正则表达式:

String regexp = "\\{[\"a-zA-Z-0-9:,\\\\]*\"key2\":\"\\{\\\\\"key2_1\\\\\":\\\\\"[a-zA-Z0-9]*\\\\\",\\\\\"key2_2\\\\\":\\\\\"[a-zA-Z0-9]*\\\\\",\\\\\"key2_3\\\\\":\\\\\"[a-zA-Z0-9]*\\\\\"\\}\"\\}[\"a-zA-Z-0-9:,\\\\]*"; 
Pattern pattern = Pattern.compile(regexp); 
Matcher matcher = pattern.matcher(text); 
if(matcher.matches()) { 
    ... // TODO: Replace all "{, \" and }" but How??? 
} 

我怎样才能用这个正则表达式来代替"{,\"。和"}{"}而不更改JSON中的键和值?

查找子字符串并使用String的替换方法将是我的备份解决方案。

同样,我的最终目标是解析输入字符串到我的Foo对象。有没有更好的方法,而不是使用正则表达式?

谢谢!

+0

它不应该像这样正常工作吗? – Shark

+0

@Shark Matcher只返回一个布尔值。我不能通过“就像这样”将字符串转换为对象。请注意key2的输入值是一个字符串,而在Foo对象中相应的字段是Bar对象。 –

+0

我的意思是,JSON已经包含一个'Bar'对象;它不应该罚款到一个'Foo'实例吗? – Shark

回答

1

进一步挖掘后,我发现这两个环节:

Gson custom deseralizer for one variable in an object

Gson custom seralizer for one variable (of many) in an object using TypeAdapter

我取得了我想要的东西,通过注册自己JsonDeserializerGsonBuilder

private static GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(Bar.class, new JsonDeserializer<Bar>() { 

    @Override 
    public Bar deserialize(JsonElement json, Type typeOfT, 
      JsonDeserializationContext context) throws JsonParseException { 
     Bar result = new Bar(); 
     String regexp = "\"\\{\\\\\"key2_1\\\\\":\\\\\"(?s).*\\\\\".\\\\\"key2_2\\\\\":\\\\\"(?s).*\\\\\",\\\\\"key2_3\\\\\":\\\\\"(?s).*\\\\\"\\}\""; 
     Pattern pattern = Pattern.compile(regexp); 
     Matcher matcher = pattern.matcher(json.toString()); 
     String modifiedJsonStr = json.toString(); 
     if(matcher.matches()) { 
      modifiedJsonStr = json.toString().replace("\"{", "{").replace("}\"", "}").replace("\\\"", "\""); 
     } 
     result = new Gson().fromJson(modifiedJsonStr, Bar.class); 
     return result; 
    } 
}); 

干杯。

2

的金科玉律是不要使用正则表达式这样的事情 :) 我的建议过于看向JSON映射器,例如Jackson

所有你需要做的:

  1. 在你的例子中修复JSON,这里不需要嵌套周围的双引号{
  2. Add Jackson依赖关系

    <dependency> 
        <groupId>com.fasterxml.jackson.core</groupId> 
        <artifactId>jackson-databind</artifactId> 
        <version>${jackson.version}</version> 
    </dependency> 
    
  3. 创建ObjectMapper,让他处理你的JSON字符串

    ObjectMapper mapper = new ObjectMapper(); 
    Foo foo = mapper.readValue("{\"key1\":\"value1\",\"key2\":" 
        + " {\"key2_1\":\"123\",\"key2_2\":\"456\",\"key2_3\":\"33333\"}}", Foo.class); 
    System.out.println(foo.toString()); 
    

希望它能帮助!

+0

问题是输入JSON不在我的控制之下:( –

+0

@ Top.Deck这不是问题,该解决方案将与任何有效的JSON输入一起工作。嵌套的特殊字符将被正确处理。 –

+0

您的代码中的输入实际上将是“{\”key1 \“:\”value1 \“,\”key2 \“:” +“{\\\”key2_1 \\\“:\\\”123 \\\“,\\\ “key2_2 \\\”:\\\“456 \”,\\\“key2_3 \\\”:\\\“33333 \\\”}}“,因此代码认为key2具有String值而不是嵌套的JSON。 –