요사이 소스를 파싱하여, Meta 정보를 추려내는 기능에 대해 고민하고 있다.
자바 Bytecode를 분석하는 것은 ASM등의 라이브러리를 활용하면 되지만, 소스를 파싱하는 것은 그리 쉽지 않았다.
Queue, Stack 써가면서 , 노가다를 쓰면서 소스에서 Field 정보(사이즈, type, padding 등을 파싱하고 있다.)
그러던중, split 함수의 유용함을 알게되었다.
함수 이름만 봐서는 단순히 split만 하는 함수인 줄 알았는데, 정규식을 사용할 수 있었던 것이다.
문자 파싱에 있어서는 정규식 만한 것이 또 없지 않은가..
사실 정규식을 쓰는 것이 아니더라도, 이제까지 substring과 indexOf를 주로 사용해 왔던 나에게는 split이 참 유용하게 활용될 수 있었다.
예를 들어,
다음의 소스에서, 필드명(NextKey)을 추출한다고 생각해 보자.
String test9 = "byteValue = FormatUtil.getNull(searchIcCardByCunoListRp.getNextKey()).getBytes();";
아래와 같이 간단히 split 두번이면 끝...
System.out.print( test9.split(".get")[2].trim().split("\\(")[0] );
첫번째 split(".get")은 ".get"이라는 문자열 기준으로 원본 String을 쪼개서 배열를 반환한다.
즉 [0]=byteValue = FormatUtil, [1]=Null(searchIcCardByCunoListRp, [2]=NextKey()), [3]=Bytes();
세번째 배열값을 받아 다시 split("\\(")을 해주면, NextKey 와 )) 로 나누어 준다.
뭐.. 당연하다고 생각할 수도 있으나, 해본 사람은 안다... ^^
그리고, 여기다가 정규식들을 써서 파싱한다면, 더욱 금상첨화....
예를 들어
다음과 같은 문자열에서, 숫자만 하나 뽑으면 이것이 위에서 찾아낸 Field 의 사이즈가 된다면,
String test10 = "byteBuffer = FormatUtil.strToByte(byteBuffer, byteValue, 15 - byteValue.length , \"L\",\" \");";
다음과 같이 찾을 수 있다.
Pattern p = Pattern.compile("(\\d+)");
Matcher m = p.matcher(test10);
System.out.println(m.find()? m.group() : 0);
결과는 15 이 된다.
그리고, "L"이 정렬에 대한 정보라면, 정규식 보다는 그냥 split을 쓰면
System.out.print( test10.split("\\\"")[1].trim() );
또한, " "이 padding 값이 된다면,
System.out.print( test10.split("\\\"")[3].trim() );
참조할 만한 링크는 http://www.tutorialspoint.com/java/java_regular_expressions.htm
이 글은 스프링노트에서 작성되었습니다.