문장에서 키워드 찾기

문장에서 특정 키워드를 찾는 예제입니다.

키워드는 정규식으로 검사하며, 특정 갯수 이상의 글자가 일치하면 그 확률을 리턴합니다.

아래 예제는 “박대리는해물과야채를싫어해요.백두산도싫어해요.동해물도싫어요” 에서 “동해물과“를 찾는 예제입니다.

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;

public class test extends Thread {
    
    public static void main(String[] args) throws Exception {
        // 탐색
        test t = new test();
        //String fullString = "동해물과백두산이마르고닳도록하느님이보우하사우리나라만세";
        String fullString   = "박대리는해물과야채를싫어해요.백두산도싫어해요.동해물도싫어요";
        String keyword = "동해물과";
        boolean isFindOne = false;
        String[] findKwds = t.findKeywordMaches(fullString, keyword, isFindOne);
        System.out.println("==============");
        
        // 결과 출력
        int kwdLength = keyword.length();
        int correct = 0;
        for(String akwd : findKwds) {
            correct = kwdLength - StringUtils.countMatches(akwd, ".");
            System.out.println(correct + "/" + kwdLength + " : ["+akwd+"] --> " + (correct*1f/kwdLength*100) + "%");
        }
    }
    
    /**
     * @param fullString 원본 문자열
     * @param keyword 찾을 키워드
     * @param isFindOne 가장 높은 확율로 한개만 찾을지 여부
     */
    private String[] findKeywordMaches(String fullString, String keyword, boolean isFindOne) {
        // 변수
        int i = keyword.length();       
        boolean isFind = false;
        List<String> rtnFindKwd = new ArrayList<String>();
        
        // 같은 글자 3개 이상까지 반복하며 탐색 
        do {
            for(String akwd : getAlikeKwd(keyword, i)) {
                if(fullString.matches(".*" + akwd + ".*")) {
                    System.out.println(akwd);
                    rtnFindKwd.add(akwd);
                    if(isFindOne) {
                        isFind = true;
                        break;
                    }
                }
            }
            if(isFindOne && isFind) break;
            System.out.println("--------------");
        } while(--i >= 3);
        
        return rtnFindKwd.toArray(new String[rtnFindKwd.size()]);
    }

    
    /**
     * @param kwd 키워드
     * @param kwd와 동일한 문자들의 갯수
     * @return 키워드를 점으로 교체한 문자열 배열
     */
    private String[] getAlikeKwd(String kwd, int correctCount) {
        // 입력값 검증
        if(kwd == null || StringUtils.isEmpty(kwd) || kwd.length() < correctCount)
            return new String[0];

        // 변수
        HashSet<String> alikeKwd = new HashSet<String>();
        int incorrectCount = kwd.length() - correctCount;
        String temp;
        
        // 점 : 0
        if(incorrectCount == 0) {
            alikeKwd.add(kwd);
        }
        // 점 : 1개 이상
        else {
            String[] upKwds = getAlikeKwd(kwd, correctCount+1);
            for(int i=0; i<kwd.length(); i++) {
                for(String tkwd : upKwds) {
                    temp = replaceDot(tkwd,i);
                    if(StringUtils.countMatches(temp, ".") == incorrectCount)
                        alikeKwd.add(temp);
                }               
            }   
        }       
    
        System.out.println("correctCount ==> " + correctCount);
        
        // 문자열 배열로 리턴
        return alikeKwd.toArray(new String[alikeKwd.size()]);
    }


    /**
     * @param kwd 원본 문자열
     * @param pos 점 찍을 위치들
     * @return pos 위치의 문자를 점으로 교체한 문자열
     */
    private String replaceDot(String kwd, int... pos) {
        // 입력값 검증
        if(StringUtils.isEmpty(kwd) || kwd == null) return null;
        
        // . 으로 교체후 리턴
        StringBuilder sb = new StringBuilder(kwd);
        for(int p : pos) {
            if(p >= 0 && kwd.length() > p) sb.setCharAt(p, '.');
        }
        return sb.toString();
    }
}

 

 

Notice

  • 이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 2.0 대한민국 라이선스에 따라 이용할 수 있습니다. 크리에이티브 커먼즈 라이선스
  • 저작권과 관련된 파일요청 및 작업요청을 받지 않습니다.
  • 댓글에 대한 답변은 늦을 수도 있습니다.
  • 댓글 남기기

    이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다