js 문자열 검색

js 문자열 검색

QA

js 문자열 검색

답변 2

본문


<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>문자열 검색</title>
  <style>
    .found { background-color: #ff0; } 
  </style>
 </head>
 <body>
    <!-- 텍스트 문자열에서 일치하는 문자열을 모두 검색하고 강조하기 -->
    <form id="textsearch">
        <textarea id="incoming" cols="150" rows="10"></textarea>
        <p>
            Search patter: <input id="pattern" type="text" />
        </p>
    </form>
    <button id="searchSubmit">Search for pattern</button>
    <div id="searchResult"></div>
    
    <script>
        
        document.getElementById("searchSubmit").onclick = function() {
 
            // 패턴 구하기
            var pattern = document.getElementById("pattern").value;
            var re = new RegExp(pattern, "g");
 
            // 문자열 구하기
            var searchString = document.getElementById("incoming").value;
            var matchArray;
            var resultString = "<pre>";
            var first = 0;
            var last = 0;
 
            // 각각의 일치하는 부분 검색
            while ( (matchArray = re.exec(searchString)) != null ) {
                last = matchArray.index;
 
                // 일치하는 모든 문자열을 연결
                resultString += searchString.substring(first, last);
 
                // 일치하는 부분에 강조 스타일이 지정된 class 추가
                resultString += "<span class='found'>" + matchArray[0] + "</span>";
                first = re.lastIndex; 
                // RegExp 객체의 lastIndex 속성을 이용해 검색 결과의 마지막 인덱스 접근 가능
            }
 
            // 문자열 종료
            resultString += searchString.substring(first, searchString.length);
            resultString += "</pre>";
 
            // 화면에 출력
            document.getElementById("searchResult").innerHTML = resultString;
        }
 
    </script>
 </body>
</html>

 

구글에서 퍼온 코드인데요 textarea에

오리온 초코파이

작성후 Search patter 에 오리온 초 검색하면 정상동작 하는데

오리온초 라고 검색해도 같은결과가 나오게 하고싶은데 잘 안되네요...

도움부탁드립니다

이 질문에 댓글 쓰기 :

답변 2

정규식으로 구현이 가능한지 모르겠네요. 차라리 스크립트를 새로 하나 짜는 게 낫지 않을까 싶네요.


    var searchString = new (function(){

        function search () {
            this.cursor   = 0;
            this.strBytes = [];
            this.srhBytes = [];
            this.ignBytes = [];
            this.res      = [];
            this.html     = '';
        }

        search.prototype.reset = function () {
            this.cursor   = 0;
            this.strBytes = [];
            this.srhBytes = [];
            this.res      = [];
            this.html     = '';
        };

        search.prototype.stringToByte = function (v) {
            return v.charCodeAt(0);
        };

        search.prototype.byteToString = function (v) {
            return String.fromCharCode(v);
        };

        search.prototype.stringToBytes = function (v) {
            let arr = [];
            for (let i = 0; i < v.length; i++) {
                arr.push(v.charCodeAt(i));
            }
            return arr;
        };

        search.prototype.ignoreString = function (arr) {
            this.ignBytes = arr.map(str => this.stringToByte(str));
        };

        search.prototype.removeItems = function (cnt) {

            let len = this.res.reduce((acc, cv) => (cv) ? acc + 1 : acc, 0);

            if (len === cnt) {
                this.res = [];

            } else {
                for (let i = 0; i < cnt; i++) {
                    this.res.pop();
                }
            }
        };

        search.prototype.init = function (string, search, ignore) {
            this.reset();
            this.strBytes = this.stringToBytes(string);
            this.srhBytes = this.stringToBytes(search);
            this.ignoreString(ignore);
        };

        search.prototype.process = function () {
            this.searching();
            this.result();

            return this.html;
        };

        search.prototype.searching = function () {

            for (let i = 0; i < this.strBytes.length; i++) {

                while (this.cursor < this.srhBytes.length) {

                    if (this.strBytes[i] === this.srhBytes[this.cursor]) {
                        this.res[i] = true;
                        this.cursor++;

                        if (this.cursor >= this.srhBytes.length)
                            this.cursor = 0;

                        break;

                    } else {

                        if (this.ignBytes.length > 0 && this.ignBytes.indexOf(this.strBytes[i]) !== -1) {
                            break;

                        } else {
                            this.removeItems(this.cursor);
                            this.cursor = 0;
                            break;
                        }
                    }
                }
            }
        };

        search.prototype.result = function () {

            var html = '';

            for (let i = 0; i < this.strBytes.length; i++) {

                let s = this.byteToString(this.strBytes[i]);

                if (this.res[i] === true) {
                    html += '<span class="found">' + s + '</span>';
                } else {
                    html += s;
                }
            }

            this.html = '<pre>' + html + '</pre>';
        };

        return search;
    }());


    document.getElementById("searchSubmit").onclick = function() {

        var search = document.getElementById("pattern").value;
        var string = document.getElementById("incoming").value;
        var ignore = [' '];
        var result = '';

        searchString.init(string, search, ignore);
        result = searchString.process();

        document.getElementById("searchResult").innerHTML = result;
    }


시간내서 짜봤습니다.
정규식으로도 가능한지 찾아봐야겠네요.


var string = document.getElementById("pattern").value;
var pattern = '';
var arr = [];
for (let i = 0; i < string.length; i++) {
    arr.push(string.substr(i, 1));
}
pattern = arr.join('([\\s]+)?');
var re = new RegExp(pattern, "g");

 

정규식으로 처리하면 생각보다 간단하네요.

기존 코드에서 위 부분만 변경하면 문제없이 동작합니다.

답변을 작성하시기 전에 로그인 해주세요.
QA 내용 검색
질문등록
전체 42
© SIRSOFT
현재 페이지 제일 처음으로