2015-01-13 1 views
0

나는 oldIdnewId을 가지고 있으며 oldIdnewId으로 바꿉니다. 내가 가지고있는 위의 코드와숫자를 중간에 수정하지 않고 완전 교체하는 방법은 무엇입니까?

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)); 
} 

, 그것뿐만 newResponse 인쇄됩니다 - 당신이 자세히 보면

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

을, 두 개의 필드가 변화를 가지고, 하나는 user_id와 두 번째 matterreplaceAll 때문에이 모든 것을 대체 할 것이다 새로운 것. 그것은 단지 새로운 번호의 전체 수를 교체해야하는 대신 임의의 수를 수정 -

  • USER_ID 876은 내가 무엇을 찾고 있어요 것은 5,575,432,193

로 변경되었다 54321

  • 문제 55787693로 변경있어 새로운 번호로 중간에. 예를 들어 user_id876은 전체 숫자이므로 87654321이 아니고 matter이 아니고 876이 중간에 있어야합니다.

    일반적으로 새 번호로 완전히 대체하고 싶습니다. 나는 중간에 뭔가를 대체하고 싶지 않아. 이 일을 할 수있는 방법이 있습니까?

  • +0

    * todd의 접근법을 사용하십시오. – user2469515

    +0

    @ user2469515 내 기본 방법으로 주석 처리 한 다른 jsonString과는 작동하지 않습니다. – john

    +2

    1. JSON 라이브러리를 사용하여 JSON을 오브젝트 트리로 디코딩하십시오. 2. 오브젝트 트리에서 번호를 변경하십시오. 3. JSON 라이브러리를 사용하여 오브젝트 트리를 다시 JSON으로 변환하십시오. – immibis

    답변

    2

    숫자가 아닌 문자를 찾기 위해 lookbehind와 lookahead를 사용해야합니다. 바꾸기를 원하지 않기 때문입니다. lookbehind 및 lookahead를 포함하여 원하는 구문은 다음과 같습니다.

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

    lookbehind의 구문은 (?<=X)하고 X 당신이 뒤에 또는 미리 확인할 수있는 것들 일치하는 표현이 어디 내다보기 위해, (?=X)입니다. lookbehinds와 lookaheads를 이해하는 방법은 각각 "선행"과 "후행"을 의미합니다.

    그래서 (?<=\D)876(?=\D)876 일치 뭔가 \D 일치 무언가에 의해 \D 일치하는 무언가가 선행 및 다음을 찾을 수 "를 의미한다. 그리고 물론, \D는 숫자가 아닌 모든 문자를 의미합니다.

    을하지만이 표현은 하지 lookbehind 및 내다 표현이 replaceAll로 대체됩니다 무엇의 일부가 아니므로하고 876 후에 교체 얻을 전에. 우리는 숫자가 아닌 문자를 원하지 않습니다.

    물론을, \D876\D과 동일 , 우리는 esc 백 슬래시를 두 배로하여 String 리터럴에 포함하면 \D"\\D"으로 기록됩니다.

    +0

    나는 이걸 시도했는데 예외가있다. '알 수없는 뒤 뒤에서의 그룹이 인덱스 4 (? <\ D) 876 (? = \ D)'근처에있다. 이게 무슨 뜻인지 모르겠다. – john

    +0

    아, 그래, 나는 오타가있다. 너 지금 해볼래? –

    +0

    내 샘플 문자열에 대해 정상적으로 작동하는 것처럼 보입니다. 몇 가지 더 많은 테스트를 해봅시다. 나는 이것이 어떻게 작동하고 그것이 무엇을하는지에 놀란다. :) – john

    3

    올바른 방법은 JSON 데이터를 JSON 데이터로 처리하는 것입니다.

    사용하는 모든 문자열 대체 또는 정규식이 깨지기 쉽고 일부 입력 JSON 문자열에 대해 코드가 손상 될 수 있습니다. 예를 들어, user_idmatter 값이 동일한 경우 어떻게됩니까? 중간에 대체하지 않는다는 가정은 단순히 실패합니다.난 당신이 다음 oldId 필요하지 않습니다 있으리라 믿고있어

    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; 
        } 
    } 
    

    :

    는 JSON 코드의 단 세 줄 것입니다 처리합니다. 입력 문자열에 user_id이 여러 개 포함될 수 있습니다. 예를 들어 확장하여 해당 JSONObject을 확인하고 바꿉니다.

    여기 www.json.org에서 org.json.jar for Java을 사용하고 있습니다. 원하는 JSON 파서를 자유롭게 사용할 수 있습니다.


    이 질문을 다시 게시했지만 거기에 완전한 JSON 문자열 형식을 제공 했으므로 again 솔루션을 제안했지만 가능한 모든 JSON 데이터 유형을 user_id으로 처리하는 업데이트를 제안했습니다.

    +0

    제안 해 주셔서 감사합니다. 내 경우에는 그게 내가 원하는, 내가 oldUid 값을 완전히 가지고있는 모든 필드를 대체하고 싶습니다. user_id와 물질 값이 동일하면 regex 솔루션에서 둘 다 교체되고 그 일을하고 싶습니다. – john

    +0

    기본적으로 이전의'user_id'가 JSON 필드와 완전히 일치하는 경우 동일한 'user_id' 값을 참조해야한다고 가정합니다. 그건 맞지 않아. 다른 JSON 필드가 동일한 값을 가질 수 없다는 것을 절대적으로 확신합니까? 'client_id','try' 또는'scoring '등. 나중에 구조가 변경되고'amount' 필드가 추가되면 어떻게 될까요? –

    +0

    내가 말한 것은 -이 'oldId' 번호를 가진 모든 필드는 newId로 바꾸고 싶습니다. user_id 필드이든, 시도 또는 점수 또는 금액이든 상관 없습니다. 그것이 내가해야 할 일이다. 예, 동의합니다. user_id 필드 만 바꾸려면 예 정규식 솔루션이 좋지 않았습니다. – john

    관련 문제