어제 정규식예제로 포스팅했던 [Java]정규식 예제 에서 마지막 예제였던
@Test public void 볼드_이탤릭체_함께치환() { String str = "이젠 나도 _지쳤어_ 그냥 *힘차게223dfefef* 발돋움 하는거야!!"; Pattern p = Pattern.compile("\\_([0-9a-zA-Z가-힣]*)\\_"); Pattern p1 = Pattern.compile("\\*([0-9a-zA-Z가-힣]*)\\*"); Matcher m = p.matcher(str); Matcher m1 = p1.matcher(str); while(m.find()) { str = str.replace(m.group(), getHtml(m.group(), EsCharacter.ITALIC)); } while(m1.find()) { str = str.replace(m1.group(), getHtml(m1.group(), EsCharacter.BOLD)); } logger.debug("## 볼드/이탤릭체 함께 치환한 문자열 : {}", str); }
위의 예제처럼, 여러개의 정규식을 별도로 선언하고 매칭해 치환하는 테스트케이스가
있었고, 수정해야될 여지가 있다고 끝맺음을 했습니다.
회사동료 정재훈씨의 도움으로 연산자 “|(or)”을 사용하여 간단히 처리하였습니다.
@Test public void 볼드_이탤릭체_함께치환2() { String str = "이젠 나도 _지쳤_어_ 그냥 *힘차게2**23dfefef* 발돋움 하는거야!!"; Pattern p = Pattern.compile("\\_([0-9a-zA-Z가-힣]*)\\_|\\*([0-9a-zA-Z가-힣]*)\\*"); Matcher m = p.matcher(str); String matchingStr = null; while(m.find()) { logger.debug("## 일치하는 문자열 : {}", m.group()); matchingStr = m.group(); if(matchingStr.contains("_")) { str = str.replace(m.group(), getHtml(m.group(), EsCharacter.ITALIC)); } if(matchingStr.contains("*")) { str = str.replace(m.group(), getHtml(m.group(), EsCharacter.BOLD)); } } logger.debug("## 볼드/이탤릭체 함께 치환한 문자열2 : {}", str); } public String getHtml(String str, EsCharacter ch) { String result = null; switch (ch) { case BOLD: result = "<b>"+replaceChBlank(str,"\\*")+"</b>"; break; case ITALIC: result = "<I>"+replaceChBlank(str,"\\_")+"</I>"; break; default: break; } return result; } public String replaceChBlank(String str, String ch) { return str.replaceAll(ch, ""); } public enum EsCharacter { BOLD, ITALIC; }
생각보다 간단하죠.
다만, 여러개의 정규식을 한번에 치환해야 할 경우에 과연 모든 것을 or로 연결해서
치환해야 하는지는 더 생각해봐야 할것 같습니다.
패턴에 대한 정규식을 따로 자료구조에 정의해서 compile 메서드의 인자로 넘기는
방법은 어떨까 싶네요.
결과적으로 똑같지만, 코드의 가독성은 훨씬 나아지지 않을까 싶습니다.
더 효율적인 해결방법을 알고 계시면 댓글 남겨주세요^^
저 같으면, 그럴 필요가 있다면 sed 같은 인터페이스의 펑션을 만들어 여러번 호출하겠습니다.
sed는 unix 명령어인데 주로 파일의 내용을 정규식 기반으로 바꾸는데 쓰입니다.
구글링하시면 금방 감 잡으실 수 있습니다.
sed 같은 인터페이스로 갈 시, 각각의 치환 로직은 인터페이스화하여 인자로 넘기면 되겠습니다.
scala나 groovy 같이 function이 first class인 언어에서는 그냥 function 자체를 인자로 넘기면 되겠지요.