11/08/2018, 19:58

Hàm xử lý cắt văn bản theo thẻ tự quy định hoặc theo dấu câu tùy chỉnh

Bài viết demo về một hàm cắt chuỗi theo các loại thẻ yêu cầu sử dụng ngôn ngữ javascrip Chú ý : bài viết của mình mục đính chính tham khảo ý kiến của mọi người để tối ưu và lưu lại kinh nghiệm mong mọi người giúp đỡ Mục đích viết hàm : mình cần xử lý việc highlightjs code cho các comment ...

Bài viết demo về một hàm cắt chuỗi theo các loại thẻ yêu cầu sử dụng ngôn ngữ javascrip

 Chú ý : bài viết của mình mục đính chính tham khảo ý kiến của mọi người để tối ưu và lưu lại kinh nghiệm mong mọi người giúp đỡ

Mục đích viết hàm : mình cần xử lý việc highlightjs code cho các comment lên sử lý theo kiểu thủ công là cho code vào các cặp thẻ khác nhau để có thẻ cắt nó trong một chuỗi string sau đó tùy là text thường hoặc là code để hiển thị tương ứng

Ví dụ đầu vào :
Sample input :
Tôi muốn hiển thị code C++ tôi đặt code C++ ở đây Kết thúc code C++ . và tôi muốn thêm code bash code bash Kết thúc chuỗi string.

Sample output : sẽ ra được một mảng sau

structureComment = [
"Tôi muốn hiển thị code C++ ",
"<cpp> tôi đặt code C++ ở đây </cpp>",
"Kết thúc code C++ . và tôi muốn thêm code bash ",
"<bash>  code bash </bash>",
"Kết thúc chuỗi string."
]

Hoặc như chính như việc mình nhúng code trong văn bản này cũng có thể xử lý bằng cách đánh dấu bằng thẻ code để highlightjs code cũng tương tự

Hàm viết gốm có 3 phần :

Phần thứ nhất : Khai báo một đối tượng chứa các thẻ quy định là một list các loại thẻ sẽ sử dụng và tên tương ứng , bạn có thể mở rộng bằng dấu chấm , dấu phẩy hoặc bất kỳ ký tự muốn cắt nào :

var listCodehighlight = {
    "<>": "  Thẻ code ",
    "<cpp>": " C++ ",
    "<xml>": " HTML, XML ",
    "<http>": " HTTP ",
    "<python>": " Python ",
    "<objectivec>": " Object-C ",
    "<javascript>": " Javascript ",
    "<php>": " Php ",
    "<bash>": " Bash ",
    "<css>": " CSS ",
    "<java>": " Java ",
    "<cs>": " C# ",
    "<json>": " Json ",
    "<markdown>": " Markdown ",
    "<ruby>": " Ruby ",
    "<perl>": " Perl ",
    "<sql>": " SQL "
};

Phần thứ 2 : Khai báo một đối tượng mảng để lưu lại tuần tự theo thứ tự các phần trong một commnet dạng như ngăn xếp để xử lý sau vậy .

var structureComment = []; 

Phần thứ 3 : Đây là hàm chính để xử lý việc cắt chuỗi và lưu vào mảng structureComment :

var analyzeComment = function (data) {
    var stringComment = data;
    var startStringComment = 0;
    var endStringComment = 0;
    var status = true;
    var cardMinLength;
    for (var cardKey in listCodehighlight) {
        if (stringComment.indexOf(cardKey) > -1) {                                                                                            
            status = false;                                                                                                                 
                if (stringComment.indexOf(cardKey) < stringComment.indexOf(cardMinLength)) {
                    cardMinLength = cardKey;
                }
            } else {
                cardMinLength = cardKey;
            }
        }
    }
    if (cardMinLength) {
        var keys = cardMinLength;
        if (stringComment.indexOf(keys) > startStringComment) {                                                                       
            endStringComment = stringComment.indexOf(keys);                                                                            
            var itemString = stringComment.substring(startStringComment, endStringComment);                                          
            if (itemString.replace(/s+/g, "").length > 0) {                                                                         
                itemString = itemString.trim();
                structureComment.push(itemString);                                                                                    
                stringComment = stringComment.replace(itemString, "");                                                                
            } else {                                                                                                                 
                stringComment = stringComment.replace(itemString, "");                                                               
            }
        } else {                                                                                                                     
            var temporary = keys.replace("<", "");
            temporary = "</" + temporary;
            if (stringComment.indexOf(temporary) > -1) {                                                                             
                status = false;
                endStringComment = stringComment.indexOf(temporary) + temporary.length;                                              

                var commentString = stringComment.substring(startStringComment, endStringComment);
                structureComment.push(commentString);                                                                                

                stringComment = stringComment.replace(commentString, "");
            } else {
                structureComment.push(stringComment);                                                                               
                stringComment = "";
            }
        }
    }
    if (status) {
        structureComment.push(stringComment);
        stringComment = "";
    }
    if (stringComment.replace(/s+/g, "").length > 0) {
        analyzeComment(stringComment);
    }
};

Mình code kiểu tay to lên nhìn code khá là dối chưa có hệ thống và hơi dối.

Hiện tại hàm xử lý của mình có các phần sau :

Phần vòng lặp :

    for (var cardKey in listCodehighlight) {
        if (stringComment.indexOf(cardKey) > -1) {                                                                                            
            status = false;                                                                                                                 
                if (stringComment.indexOf(cardKey) < stringComment.indexOf(cardMinLength)) {
                    cardMinLength = cardKey;
                }
            } else {
                cardMinLength = cardKey;
            }
        }
    }

Mục đích đoạn này là kiểm tra xem thẻ code nào gần đầu chuỗi nhất thì cắt thẻ đó trước, nếu không khi kiểm tra các loại code có trong một comment mà cắt không có thứ tự sẽ cắt thẻ này mất thẻ khác !

Đoạn code thứ 2 :

     if (stringComment.indexOf(keys) > startStringComment) {                                                                       
            endStringComment = stringComment.indexOf(keys);                                                                            
            var itemString = stringComment.substring(startStringComment, endStringComment);                                          
            if (itemString.replace(/s+/g, "").length > 0) {                                                                         
                itemString = itemString.trim();
                structureComment.push(itemString);                                                                                    
                stringComment = stringComment.replace(itemString, "");                                                                
            } else {                                                                                                                 
                stringComment = stringComment.replace(itemString, "");                                                               
            }
        }

Mục đích đoạn code này là kiểm tra xem bắt đầu một chuỗi có phải là bắt đầu 1 thẻ code nếu đúng thì cắt nó ra khỏi chuỗi . Sau khi cắt nó khỏi chuỗi cần kiểm tra nó có phải là rỗng không nếu là rỗng thì không lưu vào mảng structureComment không thì ngược lại . Sau đó cập nhật lại chuỗi string để xử lý sau

    var temporary = keys.replace("<", "");
            temporary = "</" + temporary;
            if (stringComment.indexOf(temporary) > -1) {                                                                             
                status = false;
                endStringComment = stringComment.indexOf(temporary) + temporary.length;                                              

                var commentString = stringComment.substring(startStringComment, endStringComment);
                structureComment.push(commentString);                                                                                

                stringComment = stringComment.replace(commentString, "");
            } else {
                structureComment.push(stringComment);                                                                               
                stringComment = "";
            }

Đoạn code này mục đích là tìm và cắt chuỗi code đến đoạn thẻ kết thúc code dạng (</ thẻ code >) , nếu không tìm thấy thẻ kết thúc thì lưu cả đoạn string đó vào mảng và cập nhật rỗng cho cả chuỗi string

            else {
                structureComment.push(stringComment);                                                                               
                stringComment = "";
                }

Đoạn code cuối cùng

    if (status) {
        structureComment.push(stringComment);
        stringComment = "";
    }
    if (stringComment.replace(/s+/g, "").length > 0) {
        analyzeComment(stringComment);
    }

Nếu không tồn tại thẻ code nào status = true thì lưu cả đoạn string đó là comment .
Phần dưới là nếu đoạn chuỗi còn lại nếu không phải là rỗng thì sẽ gọi đệ quy lại chính nó và chuyền xử lý tiếp đoạn string còn lại!

Hàm xử lý trên gặp một vấn đề là mỗi lần đệ quy lại sẽ mất một lần thực hiện việc tìm thẻ gần đầu chuỗi nhất để cắt hơi phí :D

    for (var cardKey in listCodehighlight) {
        if (stringComment.indexOf(cardKey) > -1) {                                                                                            
            status = false;                                                                                                                 
                if (stringComment.indexOf(cardKey) < stringComment.indexOf(cardMinLength)) {
                    cardMinLength = cardKey;
                }
            } else {
                cardMinLength = cardKey;
            }
        }
     }

Mọi người có cách giải quyết nào tối ưu hơn và đỡ rườm rà hơn càng tốt , nếu gói gọn không phải khai báo mảng bên ngoài . Mà có thể đóng gói và tối ưu hơn càng tốt.

Mọi ý kiến mình đều lắng nghe để làm tốt mong mọi người giúp đỡ. Mà nếu có cách xử lý hay hơn những bằng ngôn ngữ khác như Python hoặc C++, .. cũng có thể cho mình tham khảo ak :D

0