externalHTML.search (/ \> * \ </); // поиск по регулярному выражению по externalHTML иногда дает «неправильный» индекс - PullRequest
0 голосов
/ 19 июня 2019

хочу получить HTML для определения таблицы, извлекая из externalHTML таблицы, ища индекс '> что угодно <' </p>

, пробовал несколько шаблонов и match (), но не повезло.

<!DOCTYPE html>
<html>
    <head>     
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <!-- <thead> not on same line as <table> -->
        <table  id="t1" border="1">         
            <thead>
                <tr>   <th colspan="2">1</th><th colspan="3">22 </th></tr>
                <tr>    <th>1</th><th  data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
            </thead>
            <tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
        </table>
        <!-- <thead> on same line as <table> -->
        <table  id="t2" border="1" >  <thead>                  
                <tr>   <th colspan="2">1</th><th colspan="3">22 </th></tr>
                <tr>    <th>1</th><th  data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
            </thead>
            <tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
        </table>
        <p>
        <div id="out1"></div>
        <p>
        <div id="out2"></div>
        <script>
            /*****************************************
             * want to get the HTML for a table definition
             * by extracting <table ...> from outer html, looking
             * for the index of '> whatever <' 
             *****************************************/
            var m, t, oh, index;
            /*****************************************
             * does not work
             *****************************************/
            t = document.getElementById('t1');
            oh = t.outerHTML;
            index = oh.search(/\> *</); // what is wrong with  regex
            document.getElementById('out1').innerHTML = htmlentity(oh.substring(0, index + 1));
            /*****************************************
             * works
             *****************************************/
            t = document.getElementById('t2');
            oh = t.outerHTML;
            index = oh.search(/\> *\</);
            document.getElementById('out2').innerHTML = htmlentity(oh.substring(0, index + 1));

            function htmlentity(value) {
                value = value.replace(/&/gi, "&amp;");
                value = value.replace(/</gi, "&lt;");
                value = value.replace(/>/gi, "&gt;");
                value = value.replace(/"/gi, "&quot;");
                value = value.replace(/'/gi, "&#039;");
                return value;
            }
        </script>
    </body>
</html>

```

Первое определение таблицы, 't1', не работает с моим регулярным выражением.Второе определение таблицы, 't2', работает с моим регулярным выражением.

Вывод:

enter image description here

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

что не так с регулярным выражением

Регулярные выражения - неправильный инструмент для анализа HTML. ( Обязательная ссылка .) Они могут быть частью HTML-анализатора, но только одно выражение не подходит для этой задачи.

хочу получить HTML для определения таблицы

Я бы выбрал гораздо более прямой подход: таблица уже проанализирована, поэтому просто клонируйте ее, удалите все текстовые узлы из клона, а затем (если вам нужен HTML, а не просто дерево узлов), получите outerHTML:

function extractStructure(element) {
    const clone = element.cloneNode(true);
    removeText(clone);
    return clone.outerHTML;
}
function removeText(element) {
    let child = element.firstChild;
    while (child) {
        let next = child.nextSibling;
        if (child.nodeType === 1) { // Element
            removeText(child);
        } else if (child.nodeType === 3) { // Text
            element.removeChild(child);
        }
        child = next;
    }
}

function extractStructure(element) {
    const clone = element.cloneNode(true);
    removeText(clone);
    return clone.outerHTML;
}
function removeText(element) {
    let child = element.firstChild;
    while (child) {
        let next = child.nextSibling;
        if (child.nodeType === 1) { // Element
            removeText(child);
        } else if (child.nodeType === 3) { // Text
            element.removeChild(child);
        }
        child = next;
    }
}
console.log(extractStructure(document.getElementById("t1")));
console.log(extractStructure(document.getElementById("t2")));
<table  id="t1" border="1">         
    <thead>
        <tr>   <th colspan="2">1</th><th colspan="3">22 </th></tr>
        <tr>    <th>1</th><th  data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
    </thead>
    <tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
<!-- <thead> on same line as <table> -->
<table  id="t2" border="1" >  <thead>                  
        <tr>   <th colspan="2">1</th><th colspan="3">22 </th></tr>
        <tr>    <th>1</th><th  data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
    </thead>
    <tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
0 голосов
/ 19 июня 2019

На Т1 возвращаемся на линию

<table  id="t1" border="1">         
    <thead>

А в своем регулярном выражении вы выбираете все, что осталось после />, вероятно, пытаетесь жадничать?

Попробуйте с этим index = oh.search(/\>.*?/);

Код:

    const regexT = />.*?/;
    t = document.getElementById('t1');
    oh = t.outerHTML;
    index = oh.search(regexT);
    document.getElementById('out1').innerHTML = htmlentity(oh.substring(0, index + 1));
    t = document.getElementById('t2');
    oh = t.outerHTML;
    index = oh.search(regexT);
    document.getElementById('out2').innerHTML = htmlentity(oh.substring(0, index + 1));

Примечание: вероятно, не лучшим подходом в этом случае является сопоставление с образцом (см. Ответ Т. Дж. Краудера)

...