2015-12-28 43 views
3

將此HTML指定爲字符串「html」,如何將其拆分爲數組,其中每個標頭<h表示元素的開始?按特定標記將HTML字符串拆分爲數組

開始使用此:

<h1>A</h1> 
<h2>B</h2> 
<p>Foobar</p> 
<h3>C</h3> 

結果

["<h1>A</h1>", "<h2>B</h2><p>Foobar</p>", "<h3>C</h3>"] 

我已經試過:

我想用Array.split()用正則表達式,但結果分裂了每個<h納入自己的元素。我需要弄清楚如何從一個<h開始捕獲,直到下一個<h。然後包括第一個但排除第二個。

var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>'; 
var foo = html.split(/(<h)/); 

編輯:正則表達式是無論如何也不能要求,它只是一下子,我想用這種方式通常分裂HTML字符串工作的唯一解決方案。

+3

爲什麼要使用正則表達式是什麼? – Tomalak

+0

如果有一種方法不使用正則表達式,我完全願意使用它:) –

+0

您使用的是地球上最先進的HTML解析器中託管的語言,而不是使用這些HTML解析功能有點愚蠢。 – Tomalak

回答

7

在您的例子,你可以使用:

/ 
    <h // Match literal <h 
    (.) // Match any character and save in a group 
    > // Match literal < 
    .*? // Match any character zero or more times, non greedy 
    <\/h // Match literal </h 
    \1 // Match what previous grouped in (.) 
    > // Match literal > 
/g 
var str = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>' 
str.match(/<h(.)>.*?<\/h\1>/g); // ["<h1>A</h1>", "<h2>B</h2>", "<h3>C</h3>"] 

但請不要用正則表達式解析HTML,讀RegEx match open tags except XHTML self-contained tags

+0

這是一個了不起的SO問題/答案。 –

+2

用於支持HTML問題的正則表達式的Downvote。在你的名聲中,你應該比這更清楚。 – Tomalak

+0

Tomalak,來吧,他給我一個很好的答案,並有幫助。我明白,一般來說,正則表達式不應該用來解析HTML。但在這種情況下這是一個很好的答案。 –

0

我敢肯定有人可以減少for循環把尖括號放回去,但這是我該怎麼做。

var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>'; 

//split on >< 
var arr = html.split(/></g); 

//split removes the >< so we need to determine where to put them back in. 
for(var i = 0; i < arr.length; i++){ 
    if(arr[i].substring(0, 1) != '<'){ 
    arr[i] = '<' + arr[i]; 
    } 

    if(arr[i].slice(-1) != '>'){ 
    arr[i] = arr[i] + '>'; 
    } 
} 

此外,我們實際上可以除去第一和最後一個支架,做分裂,然後替換尖括號整個事情。

var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>'; 

//remove first and last characters 
html = html.substring(1, html.length-1); 

//do the split on >< 
var arr = html.split(/></g); 

//add the brackets back in 
for(var i = 0; i < arr.length; i++){ 
    arr[i] = '<' + arr[i] + '>'; 
} 

哦,當然這會失敗,元素沒有內容。

5

從評論的問題,這似乎是任務:

我正在採取動態降價,我從GitHub刮。然後我想將它呈現爲HTML,但將每個標題元素包裝在ReactJS <WayPoint>組件中。

以下是完全基於圖書館的,基於DOM-API的解決方案。

function waypointify(html) { 
    var div = document.createElement("div"), nodes; 

    // parse HTML and convert into an array (instead of NodeList) 
    div.innerHTML = html; 
    nodes = [].slice.call(div.childNodes); 

    // add <waypoint> elements and distribute nodes by headings 
    div.innerHTML = ""; 
    nodes.forEach(function (node) { 
     if (!div.lastChild || /^h[1-6]$/i.test(node.nodeName)) { 
      div.appendChild(document.createElement("waypoint")); 
     } 
     div.lastChild.appendChild(node); 
    }); 

    return div.innerHTML; 
} 

做同樣的用較少的代碼行一個現代化的圖書館是絕對有可能的,把它看作是一個挑戰。

這是它產生與樣品輸入:

<waypoint><h1>A</h1></waypoint> 
<waypoint><h2>B</h2><p>Foobar</p></waypoint> 
<waypoint><h3>C</h3></waypoint>