簡體   English   中英

使用javascript或jquery比較2 div元素中的文本

[英]compare text inside 2 div elements using javascript or jquery

我有以下2個div標簽

<div class="one">
    +
   +++
    +
</div>

第二個div標簽

<div class="two">
    + +   ++++  + ++  + + +
    + ++ +++ + +++ ++ + +++
    + ++ + + ++ + + + + ++ 
</div>

現在,如果.two存在.one ,我想找到什么。 有可能,如果是的話我們怎么能在javascript中做到這一點?

更新

我想檢查+模式。 我的意思是

+ +++ +

存在於.two 模式必須以.two相同順序.two

@shub答案似乎不起作用。 這是答案的JSFiddle

第1部分:

要查看數據的匹配方式,您可能需要嘗試將其轉換為字母而不是字母。

<div class="one">
    g
   tuv
    J
</div>

<div class="two">
    a b   cdef  g hi  j k l
    m no pqr s tuv wx y zAB
    C DE F G HI J K L M NO 
</div>

你必須做這樣的事情:

從以下:one.innerText = g \\ n tuv \\ n J

它需要變成一個正則表達式,如:/ g | tuv | J / g

要查看交叉匹配,請將第二類的內容復制並粘貼到此站點中並刪除“a”,“m”和“C”之前的間距: http//regexr.com/3eumc

第2部分

問題是如果“tuv”在字符串2中移動,它將不會被“g”鎖定在“J”之上的“u”之上。

為了將“g”固定在“J”問題之上的“u”之上,我們必須將其視為游戲板的二維數據集。 這意味着將字符串轉換為矩陣(數組數組),其中每個字母加上每個空格都會被放入數組槽中。 像這樣:

var matrix = [
  // 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 = columns. Remember to add +10, +20!
    [a| |b| | | |c|d|e|f| | |g| |h|i| | |j| |k| |l], // row 0
    [m| |n|o| |p|q|r| |s| |t|u|v| |w|x| |y| |z|A|B], // row 1
    [C| |D|E| |F| |G| |H|I| |J| |K| |L| |M| |N|O]    // row 2
];

現在您可以查看是否:

if ((matrix[0][13] === 'g') 
    && (matrix[1][12] === 't') && (matrix[1][13] === 'u') && (matrix[1][14] === 'v') 
    && (matrix[2][13] === 'J')) {
    /* SUCCESS when all 5 letters appear & "g" is above "u" & "u" is above "J".
    The entire cross can move left or right, but lines 1, 2 & 3 can't shift 
    independently of the other 3 lines. Otherwise it should fail.
    */
} else {
    // FAIL
}

第3部分......

我已經解決了這個矩陣搜索難題。 請訪問https://jsfiddle.net/briankueck/pern32vv/查看我的jsFiddle

以下是代碼外觀的核心。 打開jsFiddle鏈接上的調試開關,看看它是如何運行的。 :)

function getMatrix(cssSelector, canTrim) {
    // Built by, Clomp! @briankueck http://www.clomp.com
    var obj = $(cssSelector);
    if (obj) {
        var matrix = obj.text()

        /* Makes sure that we are selecting 3 lines, not 5 
         * as the example has a \n after <div ...>\n and before \n</div>
         */
        if (canTrim) {
            matrix = matrix.trim();
        }

        // Now split those 3 lines.
        matrix = matrix.split(/\n/);

        /* Trims each array in the matrix. Note: matrix[row] is a string, 
         * but we can treat a string as an array of characters.
         */
        if (canTrim) {
            // Trims each row, if desired.
            for (var row = 0; row < matrix.length; row++) {
                matrix[row] = matrix[row].trim();
            }
        } else {
            // Gets rid of spaces before matrix 1 in this demo.
            var maxLength = 0;
            var space = ' '; // You can also use a period here to see how it works.
            var tempMatrix = [];
            for (var row = 0; row < matrix.length; row++) {
                // This cuts the rows down (vertically) from 5 to 3.
                if (matrix[row].trim().length > 0) {
                    matrix[row] = matrix[row].replace(/\s/g, space);
                    matrix[row] = matrix[row].replace(/\t/g, space);
                    tempMatrix.push(matrix[row]);

                    if (matrix[row].length > maxLength) {
                        maxLength = matrix[row].length;
                    }
                }
            }

            /* This loops those 3 rows (horizontally) & slices the 1st character off 
             * each array if they are all identical & only contain spaces, which we are 
             * tracking with the period character '.' as dots.
             */
            var charactersToStrip = 0;
            for (var column = 0; column <= maxLength; column++) {
                for (var row = 0; row < tempMatrix.length; row++) {
                    if (tempMatrix[row][column] !== space) {
                        break;
                    } else if (row === (tempMatrix.length - 1)) {
                        charactersToStrip++;
                    }
                }
            }

            /* Strips characters, without removing the space before "g" 
             * and the space before "J".
             */
            for (var column = 0; column < charactersToStrip; column++) {
                for (var row = 0; row < tempMatrix.length; row++) {
                    tempMatrix[row] = tempMatrix[row].substring(1);
                }
            }
            matrix = tempMatrix;
        }
    }

    return matrix;
}

function matrixSearch(matrixOne, matrixTwo) {
    // Built by, Clomp! @briankueck http://www.clomp.com
    var space = ' '; // You can also use a period here to see how it works.

    // This is for " g". First we trim it, as we only want the "g" character.
    var searchChar = matrixOne[0].trim();

    // Next we find the lock position.
    var firstCharPosition = matrixTwo[0].indexOf(searchChar);

    var matchingRows = -1;
    if (firstCharPosition > -1) {

        // This should be 1 & not 0.
        var matchingCharInMatrixOne = matrixOne[0].indexOf(searchChar);

        // Now we can find the starting index of character 0 in each row of matrixTwo:
        var startIndex = firstCharPosition - matchingCharInMatrixOne;

        // This simultaneously scans rows 1, 2 & 3 in both matricies.
        var matchingRows = 0;
        for (var row = 0; row < matrixOne.length; row++) {
            /* We now know both the startIndex = 11 & the lock position = 12. 
             * So let's use them for "tuv" and " J".
             */
            var endIndex = startIndex + matrixOne[row].length;
            var i = -1;
            for (var column = startIndex; column < endIndex; column++) {
                i++;
                if (matrixOne[row][i] !== space) {
                    var matrixOneCharacter = matrixOne[row][i];
                    var matrixTwoCharacter = matrixTwo[row][column];
                    if (matrixOneCharacter !== matrixTwoCharacter) {
                        break;
                    } else if (column === (endIndex - 1)) {
                        // Found it!
                        matchingRows++;
                    }
                }
            }
        }
    }

    // Now we can find it:
    var isFoundInMatrixTwo = ((matchingRows > -1) 
        && (matchingRows === matrixTwo.length)) ? true : false;

    return isFoundInMatrixTwo;
}

var cssSelector1 = '.one';
var cssSelector2 = '.two';

var matrixOne = getMatrix(cssSelector1, false);
var matrixTwo = getMatrix(cssSelector2, true);

var isFound = matrixSearch(matrixOne, matrixTwo);
console.log('Is matrix 1 in matrix 2? ', isFound);

請享用!

順便說一下,來自Clomp的聖誕快樂Stack Overflow社區!

好吧,我們這里已經有了很好的答案,但是......這里有一個方法。 :)

基本上:過濾輸入,得到干凈的模式/矩陣(假設在開始時會有兩個空格 - 必須解決這個問題!),針對另一個模式進行測試(實際上 - 從兩者中制作HTML結構和數組=>比較它們)

也可以用視覺表示正在發生的事情。

代碼是暴行,可以而且應該被清理(但它有點工作,哈哈):

 spacer='-'; pattern=$('.one').text().replace(/ /g,spacer).split('\\n'); patt=pattern.filter(function(val){ if(val.indexOf('+')>=1) { return val; } }); patt = patt.map(function(x){ return x.slice(2); }); var lgth = 0; var longest; for(var i=0; i < patt.length; i++){ // http://stackoverflow.com/questions/6521245/finding-longest-string-in-array if(patt[i].length > lgth){ var lgth = patt[i].length; longest = patt[i]; } } //console.log(longest.length); longest_sequence=longest.trim().length; matrix=[]; for(j=0;j<patt.length;j++) { // if(patt[j]!=longest) { cleaned=patt[j]+spacer.repeat(longest.length-patt[j].length); cleaned=cleaned.substr(-longest_sequence); } else { cleaned=longest.trim(); } matrix.push(cleaned); } //console.log(matrix.join('\\n')); cells=[]; for(i=0;i<matrix.length;i++) { cells.push(matrix[i].split('')); $('table.small').append('<tr>'); } $( "table.small tr" ).each(function( index ) { for(j=0;j<cells[index].length;j++) { $(this).append('<td>'+cells[index][j]+'</td>'); } }); data=$('.two').text().replace(/ /g,spacer).split('\\n'); data=data.filter(function(val){ if(val.indexOf('+')>=1) { return val; } }); data = data.map(function(x){ return x.slice(2); }); //console.log(data); //console.log(data.join('\\n')); cells=[]; for(i=0;i<data.length;i++) { cells.push(data[i].split('')); $('table.big').append('<tr>'); } $( "table.big tr" ).each(function( index ) { for(j=0;j<cells[index].length;j++) { $(this).append('<td>'+cells[index][j]+'</td>'); } }); //comparing!!! pattern_arr=[]; $("table.small tr").each(function() { pattern_arr.push($(this).children().text().trim()) }); function arraysEqual(a1,a2) { /* WARNING: arrays must not contain {objects} or behavior may be undefined */ // console.log(JSON.stringify(a1)+':'+JSON.stringify(a2)); // console.log('________________________________________'); return JSON.stringify(a1)==JSON.stringify(a2); } count=-1; timer=setInterval(function(){ count++; sliced_arr=[]; slices=[]; $( "table.big tr" ).each(function( index ) { $(this).children('td').removeClass('search'); sliced=$(this).children('td').slice( count,count+longest_sequence ); slices.push(sliced); $(sliced).addClass('search'); sliced_arr.push($(sliced).text().trim()); if(arraysEqual(pattern_arr,sliced_arr)) { //$(sliced).addClass('found').removeClass('search'); $.each( slices, function( key, value ) { $(this).addClass('found').removeClass('search'); }); //$(slices).addClass('found').removeClass('search'); $('#status').text('Found!'); clearInterval(timer); } for(i=0;i<sliced_arr.length;i++) if(sliced_arr[i]=="") { clearInterval(timer); $('#status').text('Not found!'); break; } }); }, 1000); 
 .one, .two { font-size:22px; } table.big { border:1px solid #666; padding:0; border-collapse:collapse; } table.big td { border:1px solid #666; padding:5px; margin:0; } table.small { border:1px solid red; padding:0; border-collapse:collapse; } table.small td { border:1px solid red; padding:5px; margin:0; } .found { font-weight:bold; color:white; background:green; } .search { font-weight:bold; color:white; background:orange; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="one"><pre> + +++ + </pre></div> <table class="small"> </table> <div class="two"><pre> + + ++++ + ++ + + + + ++ +++ + +++ ++ + +++ + ++ + + ++ + + + + ++ </pre></div> <table class="big"> </table> <div id="status"> </div> 

@ 2619的 一篇 文章顯示了對Bliffoscope問題的興趣。 鑒於div.onediv.two的文本內容,以固定寬度字體,ascii藝術風格,是從+拼接在一起的圖片,意思是有效像素,並且 “(空格) 無效 。我們的想法是在哪個位置,我們可以把找到div.one超過div.two ,使兩種模式形成更多的交叉點。我只考慮兩個有效像素的坐標的交叉點給出圖像。

在此示例中, +替換為o以突出顯示每個匹配的交叉點。 可以在此處找到使用canvas簡化版本。

在下面的SO片段JSFiddle演示中 ,單擊“ Next和“ Previous鏈接,或按鍵盤上的箭頭按鈕以瀏覽匹配項。

_main.best_positions()返回每個可能疊加的交叉點數,具有任何誤差容_main.best_positions() ,按交叉點數排序(首先匹配更多)。

 var PatternFinder; PatternFinder = (function(win, doc, undefined) { 'use strict'; var _main = { selectors: { object_1_pattern: ".one", background_pattern: ".two", results: ".three", next_button: ".next", previous_button: ".previous", match_score: ".intersecting_coords", match_nr: ".match_nr", }, cache: { object_text_string: '', context_text_string: '' }, init: function() { _main.cache.object_text_string = $(_main.selectors.object_1_pattern).text(); _main.cache.context_text_string = $(_main.selectors.background_pattern).text(); // Parse our images from the text strings. _main.serialized_context = _main.serialize_map(_main.cache.context_text_string); _main.serialized_object = _main.serialize_map(_main.cache.object_text_string); // Find the position of the object with larger amount of intersecting coordinates _main.best_positions = _main.get_best_position(_main.serialized_context, _main.serialized_object); _main.current_result = _main.best_positions.length - 1; // Draw initial results _main.print_output(_main.current_result); // Handle user input $(_main.selectors.next_button).click(function() { _main.current_result -= 1; _main.print_output(); }); $(_main.selectors.previous_button).click(function() { _main.current_result += 1; _main.print_output(); }); // Keyboard: Arrow keys $(document).keydown(function(e) { switch (e.which) { case 37: { // left _main.current_result += 1; _main.print_output(); break; } case 39: { // right _main.current_result -= 1; _main.print_output(); break; } default: return; } e.preventDefault(); // prevent the default action (scroll / move caret) }); }, // Highlight an intersection. // Replace "+" by "o" in coords _x, _y. highlight_match: function(_x, _y, background) { var x = 0, y = 0, i = 0, output = "", c; for (i = 0; i < background.length; i += 1) { c = background[i]; if (c == "+" && x == _x && y == _y) { output = output + "o"; } else { output = output + c; } x += 1; if (c == "\\n") { x = 0; y += 1; } } return output; }, // Receive the translated serialized object, // and the original text string for the background. // Return the background text string, with the matches // between it and serialized_object highlighted. merge_and_deserialize: function(serialized_object, background) { var i; for (i = serialized_object.length - 1; i >= 0; i--) { background = _main.highlight_match(serialized_object[i][0], serialized_object[i][1], background); } return background; }, // Receive a text string like the one from the Stack Overflow ticket, // return an array of coordinates of filled in pixels (+ or space). serialize_map: function(char_map) { var x = 0, y = 0, c, i, map = []; for (i = 0; i < char_map.length; i += 1) { c = char_map[i]; if (c == "+") { map.push([x, y]); } x += 1; if (c == "\\n") { x = 0; y += 1; } } return map; }, // Find number of intersections between two images (that's where the magic happens). // Found here: https://gist.github.com/lovasoa/3361645 array_intersect: function() { var a, d, b, e, h = [], l = [], f = {}, g; g = arguments.length - 1; b = arguments[0].length; for (a = d = 0; a <= g; a += 1) { e = arguments[a].length, e < b && (d = a, b = e); } for (a = 0; a <= g; a += 1) { e = a === d ? 0 : a || d; b = arguments[e].length; for (l = 0; l < b; l += 1) { var k = arguments[e][l]; f[k] === a - 1 ? a === g ? (h.push(k), f[k] = 0) : f[k] = a : 0 === a && (f[k] = 0); } } return h; }, // Translate the coordinates of a serialized image. translate: function(coords, ix, iy) { return [coords[0] + ix, coords[1] + iy]; }, // Find in which position the object has more intersections with the background. get_best_position: function(context, object) { // Calculate image dimensions var context_width = context.sort(function(a, b) { return b[0] - a[0]; })[0][0], context_height = context.sort(function(a, b) { return b[1] - a[1]; })[0][1], object_width = object.sort(function(a, b) { return b[0] - a[0]; })[0][0], object_height = object.sort(function(a, b) { return b[1] - a[1]; })[0][1]; // Swipe context, store amount of matches for each patch position. var similaritudes = [], cx, cy, intersection, translated_object; for (cx = -object_width; cx < context_width; cx += 1) { for (cy = -object_height; cy < context_height; cy += 1) { translated_object = object.map(function(coords) { return _main.translate(coords, cx, cy); }); intersection = _main.array_intersect(context, translated_object); if (intersection.length > 0) { similaritudes.push({ coords: [cx, cy], similaritudes: intersection.length }); } } } // Return coords, // sorted by those for which number of matches was greater. return similaritudes.sort(function(a, b) { return a.similaritudes - b.similaritudes; }); }, print_output: function() { var positioned_object; // Get the coordinates of one of our matches. _main.current_result = Math.max(_main.current_result, 1); _main.current_result = Math.min(_main.current_result, _main.best_positions.length - 1); var score = _main.best_positions.slice(_main.current_result)[0].similaritudes; var best_position = _main.best_positions.slice(_main.current_result)[0].coords; // Translate our image patch to the position defined by _main.current_result. positioned_object = _main.serialized_object.map(function(coords) { return _main.translate(coords, best_position[0], best_position[1]); }); // Produce merged images (background after replace). var final_image = _main.merge_and_deserialize(positioned_object, _main.cache.context_text_string); // Print image and information $(_main.selectors.results).text(final_image); $(_main.selectors.match_score).text(score); $(_main.selectors.match_nr).text(_main.best_positions.length - _main.current_result); } }; // Expose methods _main.public_methods = { init: _main.init, }; return _main.public_methods; }(window, document)); PatternFinder.init(); 
 .one, .two { display: none; } .three { white-space: pre; font-family: "Lucida Console", Monaco, "Courier New", Courier, monospace; margin: 0 0 20px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="one"> + +++ + </div> <div class="two"> + + ++++ + ++ + + + + ++ +++ + +++ ++ + +++ + ++ + + ++ + + + + ++ </div> <h3>Match: <span class="match_nr"></span></h3> <h5>Intersecting coordinates: <span class="intersecting_coords"></span></h5> <div class="three"></div> <nav> <a class="previous" href="#">Previous</a> <a class="next" href="#">Next</a> </nav> <p><sub>Click Next and Previous or use the keyboard arrows to see other possible matches.</sub></p> 

下面的代碼片段在“兩個”div中查找所有出現的“one”模式,如標記中所寫。 結果在控制台輸出中報告(行索引和行位置)。

積分:

  1. Clomp的評論幫助我理解了問題是關於標記模式
  2. 我從Tim Down的 答案中借用了getIndicesOf

 function find() { var i, j, k; var txtOne = $('.one').text(); var txtTwo = $('.two').text(); var linesOne = txtOne.split("\\n"); // Get search patterns from "one" var patterns = getSearchPatterns(linesOne); // Get content lines from "two" var linesTwo = txtTwo.split("\\n"); while (linesTwo.length > 0 && !linesTwo[0]) { linesTwo.shift(); } // Get all the positions of all patterns in all lines var searchResults = []; var patternInLines, positionsInLine; for (i = 0; i < patterns.length; i++) { patternInLines = []; for (j = 0; j < linesTwo.length; j++) { positionsInLine = getIndicesOf(patterns[i], linesTwo[j], true); patternInLines.push(positionsInLine); } searchResults.push(patternInLines); } // Get the occurrences of all patterns at the same position on consecutive lines var results = []; var firstPatternInLine, firstPatternPosition, patternInLine, found; var firstPattern = searchResults[0]; for (j = 0; j < linesTwo.length - patterns.length; j++) { firstPatternInLine = firstPattern[j]; for (k = 0; k < firstPatternInLine.length; k++) { firstPatternPosition = firstPatternInLine[k]; found = true; for (i = 1; i < patterns.length; i++) { patternInLine = searchResults[i][j + i]; if (patternInLine.indexOf(firstPatternPosition) < 0) { found = false; break; } } if (found) { results.push({ line: j, position: firstPatternPosition }) } } } // Display results for (i = 0; i < results.length; i++) { console.log(results[i]); } if (results.length < 1) { console.log("No occurrence found"); } } // Trim the search lines to get the minimal search "block" function getSearchPatterns(lines) { var items = []; var result = []; var i, txt, offset, item; var minOffset = 1000000; var maxLength = 0; for (i = 0; i < lines.length; i++) { txt = lines[i].trim(); if (txt) { offset = lines[i].indexOf(txt); items.push({ str: txt, offset: offset }); minOffset = Math.min(offset, minOffset); } } for (i = 0; i < items.length; i++) { item = items[i]; item.offset -= minOffset; maxLength = Math.max(item.offset + item.str.length, maxLength); } for (i = 0; i < items.length; i++) { item = items[i]; result.push(paddRight(paddLeft(item.str, item.offset), maxLength)); } return result; } function paddLeft(str, count) { var padding = ""; for (var i = 0; i < count; i++) { padding += " "; } return padding + str; } function paddRight(str, length) { var result = str; while (result.length < length) { result += " "; } return result; } // Find all positions of search string in string // By Tim Down at https://stackoverflow.com/a/3410557/1009922 function getIndicesOf(searchStr, str, caseSensitive) { var searchStrLen = searchStr.length; if (searchStrLen == 0) { return []; } var startIndex = 0, index, indices = []; if (!caseSensitive) { str = str.toLowerCase(); searchStr = searchStr.toLowerCase(); } while ((index = str.indexOf(searchStr, startIndex)) >= 0) { indices.push(index); startIndex = index + searchStrLen; } return indices; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="one"> a bcd e </div> <div class="two"> ++ + ++ ++++ + ++ + + + a + + ++++ a ++ + + +bcd + a +++ + bcd ++ + +++ e +bcd + + ++ e + + + ++ ++ + e ++++++++++++++++++++++ </div> <button onclick="find()">Test!</button> 

你的jquery代碼看起來像這樣。 你可以用這個邏輯玩更多

    jQuery().ready(function(){
var lines = $(".two").text().split("\n");
for(i=1;i<=lines[1].length;i++){
    if(lines[1][i]=='+' 
  && lines[2][i-1]!='undefined' && lines[1][i]==lines[2][i-1] 
  && lines[2][i]!='undefined' && lines[1][i]==lines[2][i] 
  && lines[2][i+1]!='undefined' && lines[1][i]==lines[2][i+1]
  && lines[3][i]!='undefined' && lines[1][i]==lines[3][i] 
  ){
  console.log('exists');
  }
}
});

這是小提琴: https//jsfiddle.net/ahmadasjad/12eqhs7L/5/

在以前的帖子中有很多有趣的想法,我喜歡添加更緊湊的功能方法(它使用lodash)。 主要思想是修剪匹配的文本,並將其與目標文本上的移動窗口( 剪切 )進行比較。 在該函數的頂部還返回從左側找到匹配的位置。 看工作小提琴

function findText(text, search) {
  const width = maxWidth(search)-minTrim(search);
  const matcher = cut(search, minTrim(search),width).join('');
  return _.range(text[1].length) // create array of possible matches
            .map(col=>cut(text, col, width).join(''))
            .indexOf(matcher)+1; // and match with matcher
}

// Returns left padding size, e.g. 3 in the example
function minTrim(t) {
  return _.min(t.filter(s=>!!s).map(s=>s.length-_.trimStart(s).length))
}

// Returns window within $text at $start position with $width
function cut(text, start, width) {
  return text.map(s=>_.padEnd(s.substr(start,width),width))
}

// Returns maximum width of the line within text
function maxWidth(text) {
  return _.max(text.map(s=>s.length))
}

函數findText可以像這樣使用:

const two=document.getElementsByClassName("two")[0].innerHTML.split('\n');
const one=document.getElementsByClassName("one")[0].innerHTML.split('\n');
alert((pos=findText(two,one)) ? `found at position ${pos}` : "not found");

選項2如果字符串僅包含'+'且長度不超過64個字符,我們可以將上面的函數轉換為位掩碼匹配。 例如,將每個字符串轉換為二進制數字,然后移動目標字符串,應用搜索掩碼(例如上例中的窗口)並比較數字。 看工作小提琴

function findTextBin(text,search) {
  const toBin=str=>str.split('')
          .reduce((res,c)=>res<<1|(c==='+'?1:0),0)
  let one=search.map(toBin)
  let mask=toBin(_.max(one).toString(2).split('').map(c=>'+').join(''))
  let two=text.map(toBin)
  let length=_.max(text.map(str=>str.length))
  for(let i=length; i; i--,two=two.map(num=>num>>1))
    if(two.every((num,row)=>(num&mask)===one[row]))
      return i-mask.toString(2).length;
  return false;
}

只是一個建議,但你可以散列內容來比較它們。 此代碼使用CryptoJS庫生成MD5哈希

<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/md5.js"></script>
<script>
    var div1 = CryptoJS.MD5( $('.one').text() );
    var div2 = CryptoJS.MD5( $('.two').text() );
    if(div1 === div2) {
        // your code here
   }
</script>
$('.one').diffString($('.two').html());

假設兩者中的行數相同,以下解決方案使得查找模式變得簡單。

前提條件:

該解決方案需要模式,目標形成如下:

var pattern = [
  ' + ',
  '+++',
  ' + '
];

var target = [
  '+ +   ++++  + ++  + + +',
  '+ ++ +++ + +++ ++ + +++',
  '+ ++ + + ++ + + + + ++ '
];

我認為一個簡單的javascript操作可以做到這一點 - 逐行讀取HTML,並將其附加到數組。 如果需要,我也可以提供該代碼。

這個怎么運作:

代碼首先決定pattern的寬度,然后繼續在target數組中逐列查找這種寬度的模式。 當檢測到較低寬度的圖案或找到匹配時,循環停止。

代碼:

// Our core function
function matches(target, pattern) {

  if (pattern.length > target.length) {
    return false;
  }

  var patternWidth = findPatternWidth(pattern);
  var startIndex = 0;
  var currentPattern = getNextPattern(target, startIndex, patternWidth);

  while (patternValid(currentPattern, patternWidth)) {
    if (identicalArrays(currentPattern, pattern)) {
      return true;
    }

    startIndex++;
    currentPattern = getNextPattern(target, startIndex, patternWidth);
  }

  return false;
}

// -*-*-*-*-*- HELPER FUNCTIONS -*-*-*-*-*-*

// Finds the width of the pattern we want to match
function findPatternWidth(pattern) {
  var maxWidth = 0;

  for (var i = 0; i < pattern.length; i++) {
    if (pattern[i].length > maxWidth) {
      maxWidth = pattern[i].length;
    }
  }

  return maxWidth;
}

// Finds the next suitable pattern, starting with an index, of a maximum width
function getNextPattern(target, startIndex, maxWidth) {
  var result = [];

  for (var i = 0; i < target.length; i++) {
    result.push(target[i].substr(startIndex, maxWidth));
  }

  return result;
}

// Checks if two non-nested arrays are identical
function identicalArrays(source, target) {
  if (source.length !== target.length) {
    return false;
  }

  for (var i = 0; i < source.length; i++) {
    if (source[i] !== target[i]) {
      return false;
    }
  }

  return true;
}

// Checks if a given pattern is of given width
function patternValid(pattern, maxWidth) {
  for (var i = 0; i < pattern.length; i++) {
    if (pattern[i].length < maxWidth) {
      return false;
    }
  }

  return true;
}

我相信這種方法可以擴展到擺脫這種假設the number of rows are same in both

為了在另一個字符串中找到模式,首先找到加號相對於彼此的位置; 然后檢查第二個字符串中的加號是否處於相同的相對位置。

findCoordinates函數在模式字符串中查找相對於模式字符串中第一個加號的模式中的加號位置。 對於圖案,

 +
+++
 +

頂行中的+位於(0,0)。 第二行中的第一個+位於(-1,1),因為它位於第一個+的左下方和左側的一個位置。 類似地,其他脈沖分別為(0,1),(1,1)和(0,2)。

hasPattern函數使用相對坐標來檢查第二個字符串中是否存在模式。 對於第二個字符串中的每個+ ,它檢查相應位置是否有其他+字符以匹配模式。 對於示例模式,該函數將檢查字符是否為加號。 如果它是+ ,則它會檢查左下方,下方右下方和下方兩行的下方字符。 如果這些字符也是加號,則該函數返回true。

 function findCoordinates(string) { var rows = string.split('\\n'); var coordinates = []; var first = null; for (var i = 0; i < rows.length; i++) { for (var j = 0; j < rows[i].length; j++) { if (rows[i][j] === '+') { if (first === null) { first = {x:j, y:i}; } coordinates.push({x:j-first.x, y:i-first.y}); } } } return coordinates; } function hasPattern(string, coordinates) { var rows = string.split('\\n'); var matches = 0; var coordinate = null; for (var i = 0; i < rows.length; i++) { for (var j = 0; j < rows[i].length; j++) { if (rows[i][j] === '+') { matches = 0; for (var k = 0; k < coordinates.length; k++) { coordinate = coordinates[k]; if (rows[i + coordinate.y] && rows[i + coordinate.y][j + coordinate.x] === '+') { matches++; } } if (matches === coordinates.length) { return true; } } } } return false; } var one = document.querySelector('.one'); var two = document.querySelector('.two'); console.log(hasPattern(two.textContent, findCoordinates(one.textContent))); 
 div { font-family: monospace; white-space: pre; } 
 <div class="one"> + +++ + </div> <div class="two"> + + ++++ + ++ + + + + ++ +++ + +++ ++ + +++ + ++ + + ++ + + + + ++ </div> 

如果test patternsource pattern的線數不同,則此解決方案將不起作用。

我們的想法是創建一個模式的連續列的字符串。 然后我們可以使用indexOf輕松檢查模式是否存在

例如,這樣的模式:

1 2 3
+   +
  + 
+ + +

變成"+ + +++ +"; // equivalent of ["+ +"," ++","+ +"].join(""); "+ + +++ +"; // equivalent of ["+ +"," ++","+ +"].join("");

在此輸入圖像描述 這是小提琴https://jsfiddle.net/flyinggambit/vcav3c46/

 function getVerticalPattern(pattern){ // split the pattern in to an array, each item represents each line var pattern = pattern.split("\\n"); var numLines = pattern.length; // Find the number of lines // Find the longest string var longestString = 0; for(var i=0; i<pattern.length; ++i){ longestString = pattern[i].length; } // Rearrange the pattern var newPattern = []; for (var i=0; i<longestString; i++){ for (var j=0; j<numLines; j++){ if(pattern[j] && pattern[j].length){ // sometimes the split was creating empty strings "" newPattern.push(pattern[j][i]); } } } return newPattern.join(""); } function findPattern(testPattern, srcPattern){ return (getVerticalPattern(srcPattern)).indexOf(getVerticalPattern(testPattern)); } var srcPattern = document.getElementsByClassName("two")[0].innerHTML; var testPattern = document.getElementsByClassName("one")[0].innerHTML; var result = findPattern(testPattern, srcPattern); if(result !== -1){ console.log("pattern found"); }else{ console.log("pattern not found"); } 
 <pre class="one"> + +++ + </pre> <pre class="two"> + + ++++ + ++ + + + + ++ +++ + +++ ++ + +++ + ++ + + ++ + + + + ++ </pre> 

回答這個問題真是驚心動魄,很有趣:)

這是快速和丑陋的,還有一些錯誤檢查和優化還有待完成......但足以顯示這個概念:

var pattern = [
  '+ + ',
  '+ ++',
  '+ ++'
];

var target = [
  '+ +   ++++  + ++  + + +',
  '+ ++ +++ + +++ ++ + +++',
  '+ ++ + + ++ + + + + ++ '
];

function getAllIndexes(arr, val) {
    var indexes = [], i = -1;
    while ((i = arr.indexOf(val, i+1)) != -1){
        indexes.push(i);
    }
    return indexes;
}

function checkNextRow(pattern, target, pRow, tRow) {
  var matchePos = target[i].indexOf(pattern[0]);
}


function test(pattern, target) {
  //get pattern hights for later
  var pH = pattern.length;
  var tH = target.length;

  //target should have equal or more rows
  if (tH < pH) return 'not found';

  //which is the lowest row of the target where top row of the pattern can be matched?
  tLastTop = tH - pH;


  //function to check row of pattern
  function checkRest(pRow, tRow, hPosMatch) {
    console.log('searching for '+pattern[pRow]+' in '+target[tRow]);
    var matchPos = target[tRow].indexOf(pattern[pRow], hPosMatch);

    console.log('search result>>>>'+matchPos);
    if (matchPos >= 0 && matchPos === hPosMatch) {
      if (pRow === pH-1) {
        console.log('last row of pattern matched');
        return true; //last row of pattern matched
      } else {
        console.log('calling checkRow from itself');
        return checkRest(pRow+1, tRow+1, hPosMatch);
      }
    } else {
      console.log('pattern not found in row, returning false',hPosMatch, matchPos);
      return false;
    }
  }

  //search for top row of pattern
  for (i = 0; i <= tLastTop; i++) {
    //get all accurance indexes of patern's first row
    var matches = getAllIndexes(target[i], pattern[0]);
    console.log("matches",matches);
    if (matches.length <= 0) continue;

    //try other rows for each accurance position
    for (h = 0; h <= matches.length; h++) {
      var hPosMatch = matches[h];
      console.log('calling checkRow from iterator');
      var result = checkRest(1,i+1,hPosMatch);
      if (result) return true;
    }
  }
  return false;


}

console.log(test(pattern, target));

我跳過將DIV內容加載到模式/目標變量中,因為它似乎微不足道。 另外我假設空格對於模式也很重要,這意味着' + + '與' +++ '不匹配

JSBin在這里: http ://jsbin.com/kayeyi/edit?js,console

為了不使事情過於復雜,我對輸入做了一些假設:

  1. 輸入中的行數相等
  2. 輸入中的任何空行都可以省略
  3. 每個非空的輸入行應包含“缺失”位置的空白字符
  4. 兩個輸入中的空白字符是相同的,它不是換行符

除了從DOM收集數據外,解決方案還包括以下步驟:

  1. 模式和輸入都轉換為字符串數組,每個字符串用於一行。 數組必須具有相同的長度( 假設1
  2. 對於每對線,收集可能匹配的列表 - 輸入字符串中包含模式字符串的所有索引的列表
  3. 結果列表被展平為單個列表,並計算所有索引。 現在,對於每個可能的索引,我們都有匹配成功的行數
  4. 過濾結果以僅保留具有最大計數的索引

還有一個解決方案的工作小提琴

 function indexOf(pattern, input){ if(pattern.length !== input.length) throw 'Works only for same number of lines'; var counts = [].concat(...input.map((s,i) => allMatches(pattern[i],s))).reduce((r,e) => (r[e] = (r[e] || 0) + 1, r), {}); //find all matches for all lines and flatten the result var stops = Object.keys(counts).filter(k => counts[k] === pattern.length); //get only those that span across all the lines return stops[0] || -1; //first found or -1 if empty } function allMatches(substr, str){ var result = [], index = 0; while(~(index = str.indexOf(substr, index))) // ~(-1) is falsy result.push(index++); return result; } function readContent(element){ return (element.value || element.textContent).split(/[\\r\\n]+/).filter(s => s.length); //get all non-empty lines } function showResult(pattern, input){ var chars = Array(input[0].length).fill('\\xa0'); // &nbsp; chars[indexOf(pattern, input)] = '^'; document.querySelector('.result').textContent = chars.join(''); } function updater(){ showResult( readContent(document.querySelector('.one')), readContent(document.querySelector('.two')) ); } document.querySelector('.one').addEventListener('input', updater); document.querySelector('.two').addEventListener('input', updater); updater(); 
 .one, .two, .result{ padding: 0; margin: 0; font-family: monospace; width: 100%; font-size: 1rem; } 
 <textarea class="one" rows="4"> + +++ + </textarea> <textarea class="two" rows="4"> + + ++++ + ++ + + + + ++ +++ + +++ ++ + +++ + ++ + + ++ + + + + ++ </textarea> <div class="result"></div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM