js文本差异比较

算法是网上找的算法。。只是自己做了比较的效果

上代码直接

<!doctype html>
<html>

<head>
    <title>文本比较工具</title>
    <style type="text/css">
        .text textarea {
            resize: none;
            background: none repeat scroll 0 0 transparent;
            border: 0 none;
            width: 97%;
            height: 500px;
            overflow-y: scroll;
            position: absolute;
            left: 0;
            top: 0;
            z-index: 2;
            font-size: 18px;
            white-space: pre-wrap;
            word-wrap: break-word;
            word-break: break-all;
            border: 1px solid red;
        }

        .text {
            overflow-y: scroll;
            white-space: pre-wrap;
            word-wrap: break-word;
            word-break: break-all;
            width: 50%;
            float: left;
            text-align: left;
            z-index: 1;
            font-size: 18px;
            position: relative;
            min-height: 510px;
        }

        .add {
            color: red;
        }

        .delete {
            color: blue;
            text-decoration: line-through;
        }

        .button {
            width: 100%;
            line-height: 30px;
            font-size: 30px;
            border: 1px solid green;
            padding: 10px;
            cursor: pointer;
            text-align: center;
        }

        #result-box {
            padding: 20px;
            border: 1px solid blue;
        }
        .compare-box:after{
            content: "";
            display:block;
            clear: both;
        }
        #result{
            font-size: 20px;
        }
    </style>
</head>

<body>
    <div id="result-box">
        <pre id="result"></pre>
    </div>
    <div class="compare-box">
        <div class="text left-box">
            <textarea id="edit_textarea_1"></textarea>
        </div>
        <div class="text right-box">
            <textarea id="edit_textarea_2"></textarea>
        </div>
    </div>
    <div class="button">比较</div>
    <script type="text/javascript">
        function textchange() {
            var op = eq({ value1: document.getElementById("edit_textarea_1").value, value2: document.getElementById("edit_textarea_2").value });
            document.getElementById("result").innerHTML = op.value2 + "\r\n";
        }
        function eq(op) {
            if (!op) {
                return op;
            }
            if (!op.eq_min) {
                op.eq_min = 3;
            }
            if (!op.eq_index) {
                op.eq_index = 5;
            }
            if (!op.value1 || !op.value2) {
                return op;
            }
            var ps = {
                v1_i: 0,
                v1_new_value: "",
                v2_i: 0,
                v2_new_value: ""
            };
            while (ps.v1_i < op.value1.length && ps.v2_i < op.value2.length) {
                if (op.value1[ps.v1_i] == op.value2[ps.v2_i]) {
                    //ps.v1_new_value += op.value1[ps.v1_i].replace(/</g,"<").replace(">",">");
                    ps.v2_new_value += op.value2[ps.v2_i].replace(/</g, "<").replace(">", ">");
                    ps.v1_i += 1;
                    ps.v2_i += 1;
                    //值2增加的部分
                    if (ps.v1_i >= op.value1.length) {
                        ps.v2_new_value += "<span class='add'>" + op.value2.substr(ps.v2_i).replace(/</g, "<").replace(">", ">") + "</span>";
                        break;
                    }
                    //值1删除的部分
                    if (ps.v2_i >= op.value2.length) {
                        //ps.v1_new_value += "<span style='" + op.value1_style + "'>值1多的" + op.value1.substr(ps.v1_i).replace(/</g,"<").replace(">",">") + "</span>";
                        ps.v2_new_value += "<span class='delete'>" + op.value1.substr(ps.v1_i).replace(/</g, "<").replace(">", ">") + "</span>";
                        break;
                    }
                } else {
                    ps.v1_index = ps.v1_i + 1;
                    ps.v1_eq_length = 0;
                    ps.v1_eq_max = 0;
                    ps.v1_start = ps.v1_i + 1;
                    while (ps.v1_index < op.value1.length) {
                        if (op.value1[ps.v1_index] == op.value2[ps.v2_i + ps.v1_eq_length]) {
                            ps.v1_eq_length += 1;
                        } else if (ps.v1_eq_length > 0) {
                            if (ps.v1_eq_max < ps.v1_eq_length) {
                                ps.v1_eq_max = ps.v1_eq_length;
                                ps.v1_start = ps.v1_index - ps.v1_eq_length;
                            }
                            ps.v1_eq_length = 0;
                            break;//只寻找最近的
                        }
                        ps.v1_index += 1;
                    }
                    if (ps.v1_eq_max < ps.v1_eq_length) {
                        ps.v1_eq_max = ps.v1_eq_length;
                        ps.v1_start = ps.v1_index - ps.v1_eq_length;
                    }

                    ps.v2_index = ps.v2_i + 1;
                    ps.v2_eq_length = 0;
                    ps.v2_eq_max = 0;
                    ps.v2_start = ps.v2_i + 1;
                    while (ps.v2_index < op.value2.length) {
                        if (op.value2[ps.v2_index] == op.value1[ps.v1_i + ps.v2_eq_length]) {
                            ps.v2_eq_length += 1;
                        } else if (ps.v2_eq_length > 0) {
                            if (ps.v2_eq_max < ps.v2_eq_length) {
                                ps.v2_eq_max = ps.v2_eq_length;
                                ps.v2_start = ps.v2_index - ps.v2_eq_length;
                            }
                            ps.v1_eq_length = 0;
                            break;//只寻找最近的
                        }
                        ps.v2_index += 1;
                    }
                    if (ps.v2_eq_max < ps.v2_eq_length) {
                        ps.v2_eq_max = ps.v2_eq_length;
                        ps.v2_start = ps.v2_index - ps.v2_eq_length;
                    }
                    if (ps.v1_eq_max < op.eq_min && ps.v1_start - ps.v1_i > op.eq_index) {
                        ps.v1_eq_max = 0;
                    }
                    if (ps.v2_eq_max < op.eq_min && ps.v2_start - ps.v2_i > op.eq_index) {
                        ps.v2_eq_max = 0;
                    }
                    if ((ps.v1_eq_max == 0 && ps.v2_eq_max == 0)) {
                        //两个值的字不同
                        //ps.v1_new_value += "<span style='" + op.value1_style + "'>不同的" + op.value1[ps.v1_i].replace(/</g,"<").replace(">",">") + "</span>";
                        ps.v2_new_value += "<span class='delete'>" + op.value1[ps.v1_i].replace(/</g, "<").replace(">", ">") + "</span>";
                        ps.v2_new_value += "<span class='add'>" + op.value2[ps.v2_i].replace(/</g, "<").replace(">", ">") + "</span>";
                        ps.v1_i += 1;
                        ps.v2_i += 1;

                        if (ps.v1_i >= op.value1.length) {
                            //值2增加的部分
                            ps.v2_new_value += "<span class='add'>" + op.value2.substr(ps.v2_i).replace(/</g, "<").replace(">", ">") + "</span>";
                            break;
                        }
                        if (ps.v2_i >= op.value2.length) {
                            //值1删除的部分
                            //ps.v1_new_value += "<span style='" + op.value1_style + "'>值1多的" + op.value1.substr(ps.v1_i).replace(/</g,"<").replace(">",">") + "</span>";
                            ps.v2_new_value += "<span class='delete'>" + op.value1.substr(ps.v1_i).replace(/</g, "<").replace(">", ">") + "</span>";
                            break;
                        }
                        //值1删除的
                    } else if (ps.v1_eq_max > ps.v2_eq_max) {
                        //ps.v1_new_value += "<span style='" + op.value1_style + "'>值1删除的" + op.value1.substr(ps.v1_i, ps.v1_start - ps.v1_i).replace(/</g,"<").replace(">",">") + "</span>";
                        ps.v2_new_value += "<span class='delete'>" + op.value1.substr(ps.v1_i, ps.v1_start - ps.v1_i).replace(/</g, "<").replace(">", ">") + "</span>";
                        ps.v1_i = ps.v1_start;
                    } else {
                        //值2增加的
                        ps.v2_new_value += "<span class='add'>" + op.value2.substr(ps.v2_i, ps.v2_start - ps.v2_i).replace(/</g, "<").replace(">", ">") + "</span>";
                        ps.v2_i = ps.v2_start;
                    }
                }
            }
            op.value1 = ps.v1_new_value;
            op.value2 = ps.v2_new_value;
            //有多个连着修改的放在一起
            var addRule = /<span class='add'>((?!<span).)+<\/span>/g;
            var deleteRule = /<span class='delete'>((?!<span).)+<\/span>/g;
            var allRule = /(<span class='delete'>((?!<span).)+<\/span><span class='add'>((?!<span).)+<\/span>){2,}/g;
            op.value2 = op.value2.replace(allRule, function (str) {
                var beforText = "", afterText = "";
                var beforeMatch = str.match(deleteRule);
                for (var i = 0; i < beforeMatch.length; i++) {
                    var m = beforeMatch[i].match(deleteRule);
                    beforText += RegExp.$1;
                }
                var afterMatch = str.match(addRule);
                for (var i = 0; i < afterMatch.length; i++) {
                    var m = afterMatch[i].match(addRule);
                    afterText += RegExp.$1;
                }
                return "<span class='delete'>" + beforText + "</span><span class='add'>" + afterText + "</span>";
            });
            return op;
        }
        window.onload = function () {
            document.getElementsByClassName("button")[0].addEventListener("click", textchange);
        }
    </script>
</body>

</html>

  

posted @ 2018-09-14 15:56  吃馒头的火鸡  阅读(4913)  评论(0编辑  收藏  举报