String 한 줄 주석에서 항목값 걸러내기

2025. 5. 1. 12:36Java/소스 쪼가리

java 에서 /** 로 대표되는 javadoc 주석(예1)에서 특정 항목을 뽑아낼때 쓸 수 있는 로직이다.

예1)

/***************************************************************************
 * 제목 : 애국가
 * 작사 : (미상)
 * 작곡 : 안익태
 * 가사 : 동해물과 백두산이 ...
 * 반복부 : 무궁화 삼천리 화려강산 대한사람 대한으로 길이 보전하세
 ***************************************************************************/

 

위와 같이 여러 줄의 String 을 유지할 수만 있어도 /**, * 를 모두 없애고 String 의 split("\n") 으로 한 줄씩 걸러낸 후에

항목명 별로 걸러낼 수 있다. 하지만 JDT 의 org.eclipse.jdt.core.dom.Comment 객체를 toString() 으로 주석 문자열을 String 으로 받으면

/** 제목 : 애국가 작사 : (미상) 작곡 : 안익태 가사 : 동해물과 백두산이 ... 반복부 : 무궁화 삼천리 ...

 

처럼 개행문자 없이 한 줄로 나온다. (예1) 처럼 제목 / 작사 / 작곡 / 가사 / 반복부 로 항목순서가 일정하다는 전제 하에 항목값을 뽑으려면 다음을 준비한다.

 

Object[] keys = { ... }; // 배열에 항목명을 나열한다.

  • 항목명이 변경될 수 있는 상황을 고려해서 Object 배열로 처리하였다.
  • Object 를 쓰면 소스코드가 간결해진다.

keys 갯수만큼 values 를 받을 수 있게 String 배열을 준비한다. ( new String[keys.length] )

 

※ 유의할 점 :

  • 항목명(key) 순서는 반드시 지켜야 됨. 주석에서 항목명이 누락될 경우 더 이상 진행되지 않음!
  • 항목명을 여러번 loop 으로 검사하는 로직이 아니기 때문.
  • 주석에서 항목명이 발견되면 해당 항목명의 index 로 주석 문자열에서 제거하고 trim 한 후,
  • 구분자인 : 가 주석문자열 맨앞에 있을 경우 이것을 제거하고, 다음 번 항목명의 index 를 찾아서
  • 기존 항목값을 추려내는 방식임.

public class Test {

    public static void main(String[] args) {
        Object[] keys = {new Object[]{"제목", "타이틀"}, "작사", "작곡", "가사", new Object[]{"후렴구", "반복부"}};
        String[] values = new String[keys.length];

        String Text = "제목 : 애국가 작사 : (미상) 작곡 : 안익태 가사 : 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세 반복부 : 무궁화 삼천리 화려강산 대한사람 대한으로 길이 보전하세";

        
        int nextStIdx = 0;
        int nextKyIdx = -1;
        
        boolean avoidEscapeChar = true;
        
        for (int j = 0; j < keys.length; j++) {
            
            String key = "";
            String nxKey;
            
            int searchIdx = -1;
            boolean found = false;
            
            if (keys[j] instanceof Object[]) {
                Object[] multi = (Object[]) keys[j];
                for (int m = 0; m < multi.length; m++) {
                    key = (String) multi[m];
                    searchIdx = Text.indexOf(key);
                    found = searchIdx > -1;
                    
                    if (found) {
                        break;
                    }
                }
            } else {
                key = (String) keys[j];
                searchIdx = Text.indexOf(key);
                found = searchIdx > -1;
            }
            
            if (found) {
                nextStIdx = searchIdx + key.length();
                Text = Text.substring(nextStIdx).trim();
                
                if (Text.startsWith(":")) {

                    if (j > keys.length-1 || j == keys.length-1) {// 마지막 요소
                        nxKey = "";
                        String tmp = Text.substring(1).trim();
                        values[j] = tmp.contains("\n")? tmp.split("\n")[0].trim() : Text.substring(1).trim();
                        
                        if (avoidEscapeChar) {
                            int ccIdx = values[j].indexOf("@");
                            values[j] = ccIdx > -1? values[j].substring(0, ccIdx) : values[j];
                        }
                        
                    } else {
                        if (keys[j+1] instanceof Object[]) {
                            Object[] nxMul = (Object[]) keys[j+1];
                            
                            for (int m = 0; m < nxMul.length; m++) {
                                nxKey = (String) nxMul[m];
                                nextKyIdx = Text.indexOf(nxKey);

                                if (nextKyIdx != -1) {
                                    values[j] = Text.substring(1, nextKyIdx).trim();
                                    break;
                                }
                            }
                            
                        } else {
                            nxKey = (String)keys[j+1];
                            nextKyIdx = Text.indexOf(nxKey);
                            if (nextKyIdx != -1) {
                                values[j] = Text.substring(1, nextKyIdx).trim();
                            }
                        }
                    }
                    if (values[j] == null || values[j].trim().length() == 0) {
                        values[j] = "";
                    }
                }
            }
        }

        for (int k = 0; k < values.length; k++) {
            if (values[k] != null) {
                System.out.println("values[" + k + "] = " + values[k]);
            }
        }
    }
}

 

로직 실행결과 :

values[0] = 애국가
values[1] = (미상)
values[2] = 안익태
values[3] = 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세
values[4] = 무궁화 삼천리 화려강산 대한사람 대한으로 길이 보전하세