IT/자바, 스프링

Pattern과 Matcher로 문자열에서 원하는 값 뽑아내기

thesse 2023. 4. 22. 23:33
300x250
반응형

key1 = "value1", key2 = "value2", ....

이런 json도 아니고 요상한 형태로 날아오는 데이터를 파싱할 일이 생겼다.

 

처음엔 key-value 세트가 하나인줄 알고

단순히 따옴표 기준으로 substring을 했는데

알고보니 이게 콤마 기준으로 몇개나 될 지 랜덤하다고 한다.

흠....

 

정규표현식이랑 별로 친하진 않지만

정규표현식을 써서 Pattern을 사용하게 되었다.

 

(\w+)\s*=\s*"([^"]*)"

챗gpt와 regexr.com의 도움을 받아 이런 정규표현식이 나왔다.

  • \w+ → (\w)문자가 (+)1개 이상
  • \s* → (\s)공백이 (*)0개 이상
  • = → 부등호 그 자체
  • " → 따옴표 그 자체
  • [^"]+ → (^") 따옴표 제외한 ([])문자가 (+) 1개 이상

 

이걸로 패턴 만들어서 매처로 가져오기

 

    Pattern pattern = Pattern.compile("(\\w+)\\s*=\\s*\"([^\"]*)\"");
    Matcher matcher = pattern.matcher(input);

 

Pattern.compile()로 정규표현식을 패턴으로 가져오고

patter.matcher로 매처를 만들었다.

 

이 매처를 가지고 작업한다.

 

    Map<String, String> map = new HashMap<>();
    
    while (matcher.find() == true) {
        String key = matcher.group().substring(0, matcher.group().indexOf("=")-1);
        String value = matcher.group().substring(matcher.group().indexOf("=")+2);
        value = value.replace("\"", ""); //따옴표 지우기

        logger.info("key: {} / value: {}", key, value);
        map.put(key, value);
    }

matcher.find() 하면 정규표현식과 일치하는 문자열이 있을 경우 해당 위치로 이동하고 true를 반환한다.

이를 조건으로 while문을 돌리면 다음 일치하는 패턴으로 이동하면서 반복하게 된다.

 

내가 파싱할 문자열은 부등호 =를 기준으로 양옆에 있기에

= 위치를 indexOf로 가져오고

공백을 생각해서 키값 가져올때는 -1, 밸류값 가져올때는 +2를 해줬다.

 

그리고 밸류값은 따옴표로 둘러쌓여 있어서

이를 제거하기 위해 replace를 했다.

 

확인용으로 로그 한번 출력해주고

map에다 넣어주면 끝

로그 확인
map에 잘 들어간거 확인

300x250
반응형