테스트 사이트 - 개발 중인 베타 버전입니다

js 문자열 검색 채택완료

bonobono 5년 전 조회 2,268

</p>

<p><!doctype html></p>

<p><html></p>

<p> <head></p>

<p>  <meta charset="UTF-8"></p>

<p>  <title>문자열 검색</title></p>

<p>  <style></p>

<p>    .found { background-color: #ff0; } </p>

<p>  </style></p>

<p> </head></p>

<p> <body></p>

<p>    <!-- 텍스트 문자열에서 일치하는 문자열을 모두 검색하고 강조하기 --></p>

<p>    <form id="textsearch"></p>

<p>        <textarea id="incoming" cols="150" rows="10"></textarea></p>

<p>        <p></p>

<p>            Search patter: <input id="pattern" type="text" /></p>

<p>        </p></p>

<p>    </form></p>

<p>    <button id="searchSubmit">Search for pattern</button></p>

<p>    <div id="searchResult"></div></p>

<p>    </p>

<p>    <script></p>

<p>        </p>

<p>        document.getElementById("searchSubmit").onclick = function() {</p>

<p> </p>

<p>            // 패턴 구하기</p>

<p>            var pattern = document.getElementById("pattern").value;</p>

<p>            var re = new RegExp(pattern, "g");</p>

<p> </p>

<p>            // 문자열 구하기</p>

<p>            var searchString = document.getElementById("incoming").value;</p>

<p>            var matchArray;</p>

<p>            var resultString = "<pre>";</p>

<p>            var first = 0;</p>

<p>            var last = 0;</p>

<p> </p>

<p>            // 각각의 일치하는 부분 검색</p>

<p>            while ( (matchArray = re.exec(searchString)) != null ) {</p>

<p>                last = matchArray.index;</p>

<p> </p>

<p>                // 일치하는 모든 문자열을 연결</p>

<p>                resultString += searchString.substring(first, last);</p>

<p> </p>

<p>                // 일치하는 부분에 강조 스타일이 지정된 class 추가</p>

<p>                resultString += "<span class='found'>" + matchArray[0] + "</span>";</p>

<p>                first = re.lastIndex; </p>

<p>                // RegExp 객체의 lastIndex 속성을 이용해 검색 결과의 마지막 인덱스 접근 가능</p>

<p>            }</p>

<p> </p>

<p>            // 문자열 종료</p>

<p>            resultString += searchString.substring(first, searchString.length);</p>

<p>            resultString += "</pre>";</p>

<p> </p>

<p>            // 화면에 출력</p>

<p>            document.getElementById("searchResult").innerHTML = resultString;</p>

<p>        }</p>

<p> </p>

<p>    </script></p>

<p> </body></p>

<p></html></p>

<p>

 

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

오리온 초코파이

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

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

도움부탁드립니다

댓글을 작성하려면 로그인이 필요합니다.

답변 2개

채택된 답변
+20 포인트
SLOOP
5년 전

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

로그인 후 평가할 수 있습니다

답변에 대한 댓글 2개

S
SLOOP
5년 전
[code]
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;
}
[/code]

시간내서 짜봤습니다.
정규식으로도 가능한지 찾아봐야겠네요.
b
bonobono
5년 전
감사합니다 많은 도움이 되었습니다

댓글을 작성하려면 로그인이 필요합니다.

SLOOP
5년 전

var string = document.getElementById("pattern").value;

var pattern = '';

var arr = [];</p>

<p>for (let i = 0; i < string.length; i++) {

    arr.push(string.substr(i, 1));

}</p>

<p>pattern = arr.join('([\\s]+)?');</p>

<p>var re = new RegExp(pattern, "g");</p>

<p>

 

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

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

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인