【问题标题】:insert html elements into string of text to match another string of html将 html 元素插入到文本字符串中以匹配另一个 html 字符串
【发布时间】:2016-05-16 23:44:57
【问题描述】:

有两个文件 pdf 和 html,将文件读取为纯文本字符串(从 pdf 中提取文本后)和 html,现在尝试使纯文本具有与 html 字符串相同的 html 标签。然后比较它们以发现差异

简单示例的最终编辑当前无法正常工作

var text1="here is example text";

var text2="<html><body><div>here is another <span>example</span> text</div></body></html>";

var div = document.createElement("div");
div.innerHTML = text2;
var text = div.textContent || div.innerText || "";

var content=  text.split(" ");
var alltags=text2.match(/<.+?>/g);
var pdfwords=text1.split(" ");
var output="";
for(var j=0; j<alltags.length; j++){
   for(i=0; i<pdfwords.length; i++){
      if(pdfwords[i]===content[j]){

         output+=alltags[i]+pdfwords[i];
      }
    }
}

document.write(output);

输出应该是

"<html><body><div>here is another<span>example</span> text</div></body></html>"

diff 这两个字符串输出和 text2 显示差异为插入“另一个”

【问题讨论】:

  • 为什么不去掉html标签,只比较纯文本?
  • 这不起作用,因为 pdf 文本的位置可能与 html 文本相距几行,所以它不匹配,我已经尝试过了,而且 html 文本也有一个额外的部分
  • 提供的html包含大量的css、javascript标签、内联javascript、meta标签和html注释。因此,如果您想保留它们并进行比较,则不可能创建一些自动算法来做到这一点。所以首先,你必须明确你想要比较什么,因为在这种情况下比较&lt;script language="JavaScript" src="./javatest_files/metrics_group1.js"&gt;&lt;/script&gt;是没有意义的
  • 忽略脚本标签,只关注标记所以html标签和内联css
  • 您在尝试剥离标签和比较中提到的额外部分是什么

标签: javascript jquery html css compare


【解决方案1】:

这是您想要的简单解决方案,它是一个动态解决方案,因为它会处理找到的任何标签并仅比较文本内容。 findDiff() 会发现差异并以输出和不同单词的数组作为参数调用回调函数。

JSFiddle:https://jsfiddle.net/9svuc7om/18/

/**
 * Parse and construct an Array of PDF text tokens
 * @params {string} text   The PDF text to be parsed
 * @return {object}         The parsed Array of tokens
 */
function parsePDFText(text) {
    var token = text.split(' ');
    for (var i=0,l=token.length; i<l; i++) {
        // remove token of first space and consecutive space
        if (token[i] == '') {
            token.splice(i, 1);
        }
    }
    return token;
}

/**
 * Return the minimum indexOf among all the arguments
 * @params {...number} index  The indexOf
 * @return {number}           The minimum indexOf, -1 if all arguments are -1
 */
function findMinIndex() {
    var min;
    for (var i = 0, l = arguments.length; i < l; i++) {
        // indexOf() returns -1 if not found
        if (arguments[i] === -1) {
            continue;
        }
        if (typeof min === 'undefined' || arguments[i] < min) {
            min = arguments[i];
        }
    }
    return min || -1;
}

/**
 * Parse and construct an Array of HTML tokens
 * @params {string} text   The HTML text to be parsed
 * @return {object}       The parsed Array of tokens
 */
function parseHTMLText(text) {
    var currentIndex = 0,
        tl = text.length,
        tokens = [],
        token, firstChar, endPos;
    while (currentIndex < tl) {
        // determine the next token type
        firstChar = text.charAt(currentIndex);
        if (firstChar == '<') {
            // a tag
            // find the position of closing tag, assume all tags are well formed
            endPos = text.indexOf('>', currentIndex + 1) + 1;
            token = {
                type: 'tag',
                content: text.slice(currentIndex, endPos), 
                valid: true
            }
            currentIndex = endPos;
        } else if (firstChar == ' ') {
            // a space
            token = {
                type: 'space', 
                content: ' ', 
                valid: true
            }
            currentIndex++;
        } else {
            // a character, possibliy part of a word
            // find the end of the word
            // assume a word is delimitered either by tags or space
            endPos = findMinIndex(text.indexOf('<', currentIndex), text.indexOf(' ', currentIndex));
            // endPos is `-1` if there are not delimiter anymore, end of string reached
            if (endPos === -1) {
                endPos = tl;
            }
            token = {
                type: 'text',
                content: text.slice(currentIndex, endPos), 
                valid: true
            }
            currentIndex = endPos;
        }
        tokens.push(token);
    }
    return tokens;
}

/**
 * Find the difference between pdf text and html text and pass the output and differenc to a callback function
 * @params {string} pdfText     The pdf text
 * @params {string} htmlText    The html text
 * @params {function} callback  The callback function
 */
function findDiff(pdfText, htmlText, callback) {
    var output = '', // the final output
        diff = [], // the array of different words
        pdfTokens = parsePDFText(pdfText),
        htmlTokens = parseHTMLText(htmlText), 
        j=0, hl=htmlTokens.length;
    // the pdf text is the reference point, i.e. all the words in pdf text should always be present in html text as well
    for (var i=0,pl=pdfTokens.length; i<pl; i++) {
        // find the first occurrence of the pdf text
        for(; j<hl; j++) {
            if (htmlTokens[j].type != 'text') {
                // exclude comparison to non-text
                continue;
            }
            // check if the two text matches
            if (htmlTokens[j].content == pdfTokens[i]) {
                // a match is found
                j++;
                break;
            } else {
                // push the different html token into `diff` array
                diff.push(htmlTokens[j].content);
                // set the `valid` field of token to false
                htmlTokens[j].valid = false;
            }
        }
    }
    // invalidate the rest of the html text
    for(; j<hl; j++) {
        if (htmlTokens[j].type == 'text') {
            htmlTokens[j].valid = false;
        }
    }
    // concat the final string to output
    for (j=0; j<hl; j++) {
        if (htmlTokens[j].valid) {
            output += htmlTokens[j].content;
        }
    }
    callback(output, diff);
}

你可以通过使用来调用函数

findDiff(text1, text2, function(output, diff) {
    console.log(output);
    console.log(diff);
});

但是,此解决方案存在一些限制

  1. 假定 pdf 中的所有内容都存在于 HTML 文本中
  2. 它只处理&lt;&gt; 和空格,如果有其他可能的分隔符,例如选项卡,需要额外的代码
  3. 它假设所有标签都是格式正确的,并且文本内容之间不会有结束标签(如果你需要你应该使用&amp;gt;&amp;lt;
  4. 该功能是一种简化的解决方案,尚未经过全面测试。您不能期望它有任何保证,并且需要进行一些调整。我建议只提供 body 内的内容,甚至是更窄的范围,而不是整个 HTML 文件(如果你的情况可能的话),因为 HTML 文件的内容会有太多变化。

【讨论】:

  • 谢谢,我认为由于限制,我实际上无法比较它们,只能在 html 中获取 PDF 文本,但这对我不起作用
  • 我只是为输出的空 html 标签获得了很多空白
  • 不适用于小提琴中的简单示例说一切都不同jsfiddle.net/9svuc7om/17 甚至不会显示输出
  • @AK0101 抱歉,parsePDFToken() 中存在错误,我错过了第一个字符是空格和/或有连续空格的情况。我已经修改并制作了一个新版本:https://jsfiddle.net/9svuc7om/18/
  • 在您的演示示例中,我仍然得到一半的输出,并且有很多不同之处。输出停止在“为什么下载”
【解决方案2】:

最简单的方法是

var s="Hello everyone on stackoverflow"
var s_split = s.split(' ');
var y = '<html><head></head><body><div>' + s_split[0] + '<span>' + s_split[1] + '</span>' + s_split[2]+' ' + s_split[3] + '</div></body></html>';

查看jsfiddle

【讨论】:

  • 其实并没有发现区别,标记一下。
  • 原题修改了几次。并且他删除了他想要修改 pdf 的原始 HTML 部分。如果您真的想知道原始 HTML 和区别,可以查看我们在此处讨论的聊天室 chat.stackoverflow.com/rooms/112103/…。您会注意到向其中添加 HTML 标记是多么不可能。我说服他去掉所有不必要的 html 标签,如
【解决方案3】:

为什么不简单地去除 html 标签并比较文本。

var s = "Hello everyone on stackoverflow";

var y = "<html><head><head><body><div>Hello<span>everyone</span>on stackoverflow</div></body></html>";

//using regular expressions match HTML tags and replace them with empty string. Make sure to trim the output so that the extra whitespaces at either end are removed.
var z = y.replace(/(<([^>]+)>)/ig, ' ').trim();

//compare if the stripped string matches the other string.
if(z == s) {
    s = y;  
}
alert(s);

fiddle

【讨论】:

    【解决方案4】:

    如果您必须换行特定的单词或文本,然后搜索并替换它,如下所示:

    var f = "Hello everyone on stackoverflow";
    var o = "Hello";
    var e = "everyone on";
    var s = "stackoverflow";
    
    if (f.indexOf(e) >= 0) {
        var h = f.replace(e,"<strong>"+e+"</strong>");
    }else{
        var h = f;
    }
    if (h.indexOf(s) >= 0){
        var h = h.replace(s,"<em>"+s+"</em>");
    }
    if (h.indexOf(o) >= 0){
        var h = h.replace(o,"<u>"+o+"</u>");
    }
    
    $('body').append('<div>'+h+'</div>');
    

    此处示例:https://jsfiddle.net/jwqrgsL1/1/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-10
      • 2022-01-02
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多