[Java]정규식 “|(or)” 사용하기

어제 정규식예제로 포스팅했던 [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 메서드의 인자로 넘기는

방법은 어떨까 싶네요.

결과적으로 똑같지만, 코드의 가독성은 훨씬 나아지지 않을까 싶습니다.

더 효율적인 해결방법을 알고 계시면 댓글 남겨주세요^^

Advertisements

[Java]정규식 “|(or)” 사용하기”에 대한 2개의 생각

  1. 저 같으면, 그럴 필요가 있다면 sed 같은 인터페이스의 펑션을 만들어 여러번 호출하겠습니다.
    sed는 unix 명령어인데 주로 파일의 내용을 정규식 기반으로 바꾸는데 쓰입니다.
    구글링하시면 금방 감 잡으실 수 있습니다.

  2. sed 같은 인터페이스로 갈 시, 각각의 치환 로직은 인터페이스화하여 인자로 넘기면 되겠습니다.
    scala나 groovy 같이 function이 first class인 언어에서는 그냥 function 자체를 인자로 넘기면 되겠지요.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중