우리는 종종 한글로 검색을 할 때 한영변환 키를 누르지 않고 타이핑을 하여 영어로 입력하곤 한다.
사용자 편의성을 위해 영어로 검색을 해도 한글로 검색이 되는 앱을 만들기 위한 코드를 찾아보았다.
사내 서버가 자바로 되어 있었기 때문에 자바로 된 코드를 검색하였다.
돌려보니 어느정도 잘 돌아가는 것 같다.
asdf 같은 의미없는 단어는 한글로 변환이 잘 안되는 것 같았다.
한글을 입력 시 ??로 나와서 이 부분은 정규표현식으로 예외처리를 해주었다.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EnToKo { // 코드타입 - 초성, 중성, 종성
static enum CodeType { chosung, jungsung, jongsung }
static String ignoreChars = "`1234567890-=[]\\;',./~!@#$%^&*()_+{}|:\"<>? ";
/** * 영어를 한글로... */
public static String engToKor(String eng) { StringBuffer sb = new StringBuffer();
int initialCode = 0, medialCode = 0, finalCode = 0;
int tempMedialCode, tempFinalCode; for (int i = 0; i < eng.length(); i++) { // 숫자특수문자 처리
if(ignoreChars.indexOf(eng.substring(i, i + 1)) > -1){
sb.append(eng.substring(i, i + 1));
continue;
}
// 초성코드 추출
initialCode = getCode(CodeType.chosung, eng.substring(i, i + 1));
i++;
// 다음문자로
// 중성코드 추출
tempMedialCode = getDoubleMedial(i, eng);
// 두 자로 이루어진 중성코드 추출
if (tempMedialCode != -1) {
medialCode = tempMedialCode; i += 2;
} else {
// 없다면,
medialCode = getSingleMedial(i, eng);
// 한 자로 이루어진 중성코드 추출
i++;
}
// 종성코드 추출
tempFinalCode = getDoubleFinal(i, eng);
// 두 자로 이루어진 종성코드 추출
if (tempFinalCode != -1) {
finalCode = tempFinalCode;
// 그 다음의 중성 문자에 대한 코드를 추출한다.
tempMedialCode = getSingleMedial(i + 2, eng);
if (tempMedialCode != -1) {
// 코드 값이 있을 경우
finalCode = getSingleFinal(i, eng);
// 종성 코드 값을 저장한다.
} else {
i++;
}
} else {
// 코드 값이 없을 경우 ,
tempMedialCode = getSingleMedial(i + 1, eng);
// 그 다음의 중성 문자에 대한 코드 추출.
if (tempMedialCode != -1) {
// 그 다음에 중성 문자가 존재할 경우,
finalCode = 0; // 종성 문자는 없음.
i--;
}
else {
finalCode = getSingleFinal(i, eng);
// 종성 문자 추출
if (finalCode == -1){
finalCode = 0; i--;
// 초성,중성 + 숫자,특수문자,
//기호가 나오는 경우 index를 줄임.
}
}
}
// 추출한 초성 문자 코드,
//중성 문자 코드, 종성 문자 코드를 합한 후 변환하여 스트링버퍼에 넘김
sb.append((char) (0xAC00 + initialCode + medialCode + finalCode));
}
return sb.toString();
}
/** * 해당 문자에 따른 코드를 추출한다. * * @param type * 초성 : chosung, 중성 : jungsung, 종성 : jongsung 구분 * @param char 해당 문자 */
static private int getCode(CodeType type, String c) {
// 초성
String init = "rRseEfaqQtTdwWczxvg";
// 중성
String[] mid = { "k", "o", "i", "O", "j", "p", "u", "P", "h", "hk", "ho", "hl", "y", "n", "nj", "np", "nl", "b", "m", "ml", "l" };
// 종성
String[] fin = { "r", "R", "rt", "s", "sw", "sg", "e", "f", "fr", "fa", "fq", "ft", "fx", "fv", "fg", "a", "q", "qt", "t", "T", "d", "w", "c", "z", "x", "v", "g" };
switch (type) {
case chosung:
int index = init.indexOf(c);
if (index != -1) { return index * 21 * 28; }
break;
case jungsung:
for (int i = 0; i < mid.length; i++) {
if (mid[i].equals(c)) {
return i * 28;
}
}
break;
case jongsung:
for (int i = 0; i < fin.length; i++) {
if (fin[i].equals(c)) {
return i + 1;
}
}
break;
default:
System.out.println("잘못된 타입 입니다");
}
return -1;
}
// 한 자로 된 중성값을 리턴한다
// 인덱스를 벗어낫다면 -1을 리턴
static private int getSingleMedial(int i, String eng) {
if ((i + 1) <= eng.length()) {
return getCode(CodeType.jungsung, eng.substring(i, i + 1));
} else {
return -1;
}
}
// 두 자로 된 중성을 체크하고, 있다면 값을 리턴한다.
// 없으면 리턴값은 -1
static private int getDoubleMedial(int i, String eng) {
int result; if ((i + 2) > eng.length()) {
return -1;
} else {
result = getCode(CodeType.jungsung, eng.substring(i, i + 2));
if (result != -1) { return result; } else { return -1;
}
}
}
// 한 자로된 종성값을 리턴한다
// 인덱스를 벗어낫다면 -1을 리턴
static private int getSingleFinal(int i, String eng) {
if ((i + 1) <= eng.length()) {
return getCode(CodeType.jongsung, eng.substring(i, i + 1));
} else {
return -1;
}
}
// 두 자로된 종성을 체크하고, 있다면 값을 리턴한다.
// 없으면 리턴값은 -1
static private int getDoubleFinal(int i, String eng) {
if ((i + 2) > eng.length()) {
return -1;
} else {
return getCode(CodeType.jongsung, eng.substring(i, i + 2));
}
}
public static void main(String[] args) {
boolean isEnglish = true;
Scanner scan = new Scanner(System.in);
System.out.println(EnToKo.engToKor("zjavbxjfmf tkTek."));
// 컴퓨터를 샀다.
System.out.println("한글을 영타로 입력");
String typoText = scan.nextLine();
Pattern p = Pattern.compile("[a-zA-Z0-9]");
Matcher m = p.matcher(typoText);
// System.out.println("Found = " + (m.find() ? "True" : "Flase"));
// if (m.find()) {
// String str = typoText.substring(m.start(), m.end());
// System.out.println("Result = " + str);
// }
isEnglish = m.find();
if(isEnglish) {
String fixedText = EnToKo.engToKor(typoText);
System.out.println(fixedText);
} else {
System.out.println("영어와 숫자가 아닙니다.");
}
scan.close();
}
}
https://stackoverflow.com/questions/14290857/sql-select-where-field-contains-words