How to replace a number completly without modifying in the middle?

回眸只為那壹抹淺笑 提交于 2019-12-12 02:05:40

问题


I have oldId and newId and I want to replace oldId with newId.

public static void main(String[] args) {
    String jsonString = "{\"user_id\":{\"long\":876},\"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";

    // some other json strings -

    // String jsonString = "{\"user_id\":{\"string\": \"876\"},\"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";
    // String jsonString = "{\"user_id\": \"876\", \"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";
    // String jsonString = "{\"user_id\": 876, \"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";
    // String jsonString = "{\"user_id\": null, \"client_id\":{\"int\":0},\"affinity\":[{\"try\":{\"long\":55787693},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}";

    String newResponse = changeJsonString(jsonString, "876", "54321");
    System.out.println(newResponse);
}

private static String changeJsonString(String originalResponse, String oldId, String newId) {     
    return originalResponse.replaceAll(String.valueOf(oldId), String.valueOf(newId));
}

With the above code I have, it will print newResponse as -

{\"user_id\":{\"long\":54321},\"client_id\":{\"int\":0},\"affinity\":[{\"matter\":{\"long\":5575432193},\"scoring\":{\"float\":0.19}},{\"try\":{\"long\":1763},\"scoring\":{\"float\":0.0114}}]}    

If you see closely, two fields got change, one is user_id and second is matter since replaceAll will replace everything to a new one.

  • user_id 876 got change to 54321
  • matter 55787693 got change to 5575432193

What I am looking for is - It should only replace the full number to a new number instead of modifying any number in the middle to a new number. As an example - user_id 876 is a full number so it should replace 876 only to 54321 notmatter in which 876 is in the middle.

In general, I want to replace a number to a new number completely. I don't want to replace something in the middle of it. Is there any way to do this?


回答1:


You need to use lookbehind and lookahead to find the non-digit characters, because you don't want to replace them. The syntax that you want, including the lookbehind and lookahead is this.

originalResponse.replaceAll("(?<=\\D)" + oldId + "(?=\\D)", String.valueOf(newId));

The syntax for a lookbehind is (?<=X) and for a lookahead is (?=X), where X is an expression matching what you'll find behind or ahead. The way to understand lookbehinds and lookaheads is that they mean "preceded by" and "followed by" respectively.

So (?<=\D)876(?=\D) means "find something that matches 876, preceded by something that matches \D and followed by something that matches \D. And of course, \D means any character that is not a digit.

But this expression is not the same as \D876\D, because the lookbehind and lookahead expressions aren't part of what gets replaced by the replaceAll. We don't want the non-digit characters before and after the 876 to get replaced.

And of course, we escape the backslashes in a String literal by doubling them, so \D is written "\\D".




回答2:


The correct way would be to process JSON data as a JSON data.

Any string substitution or regex you employ would be fragile and could potentially break your code for some input JSON string. For example, what if, both user_id and matter values come in to be the same. Your assumption of not replacing in the middle simply fails then.

To process the JSON is just three lines of code:

private static String changeJsonString(String originalResponse, String newId) {     
    try {
        JSONObject root = new JSONObject(originalResponse);
        ((JSONObject) root.get("user_id")).put("long", Long.parseLong(newId));
        return root.toString();
    } catch (JSONException e) {
        e.printStackTrace();
        return null;
    }
}

I'm assuming you wouldn't require oldId then. In case, your input string could contain multiple user_ids, you would simply extend my example to check and replace the appropriate JSONObject.

Please note that I'm using the org.json.jar for Java from www.json.org. You're free to use any JSON parser you like.


Since, you've re-posted this question but have provided the complete JSON string format there, I've proposed this solution again but with updates that handle all your possible JSON data types for user_id.

来源:https://stackoverflow.com/questions/27914305/how-to-replace-a-number-completly-without-modifying-in-the-middle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!