String 한 줄 주석에서 항목값 걸러내기
2025. 5. 1. 12:36ㆍJava/소스 쪼가리
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] = 무궁화 삼천리 화려강산 대한사람 대한으로 길이 보전하세