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에다 넣어주면 끝
300x250
반응형