自動 HTML 摘要/預告片
在生成 HTML 內容預告片或摘要時,許多人只是在抓取最左邊的 n 之前剝離所有標籤 人物。最近在 ColdFusion 開發人員 Ben Nadel 的博客上,他使用 ColdFusion 及其底層 Java 方法解決了在截斷字符串中關閉 XHTML 標記的問題。看到這個之後,我創建了一個大致等效的 JavaScript 版本,並添加了一些額外的功能。具體來說,以下代碼還會為您截斷字符串(基於用戶指定的字符數),並且在此過程中僅將 HTML 標記之外的文本計入長度,避免在標記或單詞中間結束字符串,並避免為像 <br>
這樣的單例元素添加結束標籤 或 <img>
.
function getLeadingHtml (input, maxChars) { // token matches a word, tag, or special character var token = /\w+|[^\w<]|<(\/)?(\w+)[^>]*(\/)?>|</g, selfClosingTag = /^(?:[hb]r|img)$/i, output = "", charCount = 0, openTags = [], match; // Set the default for the max number of characters // (only counts characters outside of HTML tags) maxChars = maxChars || 250; while ((charCount < maxChars) && (match = token.exec(input))) { // If this is an HTML tag if (match[2]) { output += match[0]; // If this is not a self-closing tag if (!(match[3] || selfClosingTag.test(match[2]))) { // If this is a closing tag if (match[1]) openTags.pop(); else openTags.push(match[2]); } } else { charCount += match[0].length; if (charCount <= maxChars) output += match[0]; } } // Close any tags which were left open var i = openTags.length; while (i--) output += "</" + openTags[i] + ">"; return output; };
這都是很簡單的東西,但我想我還是把它傳下去吧。
這是一個輸出示例:
var input = '<p><a href="http://www.realultimatepower.net/">Ninjas</a> are mammals<br>who <strong><em>love</em> to <u>flip out and cut off people\'s heads all the time!</u></strong></p>'; var output = getLeadingHtml(input, 40); /* Output: <p><a href="http://www.realultimatepower.net/">Ninjas</a> are mammals<br>who <strong><em>love</em> to <u>flip out </u></strong></p> */
編輯: 在相關的說明中,這是我之前在 Ben 的網站上發布的一個正則表達式,它匹配字符串中的前 100 個字符,除非它在 HTML 標記的中間結束,在這種情況下它將匹配到標記的結尾(使用這個帶有“點匹配換行符”修飾符):
^.{1,100}(?:(?<=<[^>]{0,99})[^>]*>)?
這應該適用於 .NET、Java 和 JGsoft 正則表達式引擎。由於 {0,99}
在大多數其他人中不起作用 在後面。請注意,.NET 和 JGsoft 實際上支持無限長度的後視,因此您可以使用這兩個替換 {0,99}
*
的量詞 .由於 .NET 和 JGsoft 引擎還支持基於環視的條件,您可以通過將其編寫為 ^.{1,100}(?(?<=<[^>]{0,99})[^>]*>)
來節省兩個字符 .
如果你想模仿 JavaScript 中的lookbehind,你可以使用以下代碼:
// JavaScript doesn't include a native reverse method for strings, // so we need to create one String.prototype.reverse = function() { return this.split("").reverse().join(""); }; // Mimic the regex /^[\S\s]{1,100}(?:(?<=<[^>]*)[^>]*>)?/ through // node-by-node reversal var regex = /(?:>[^>]*(?=[^>]*<))?[\S\s]{1,100}$/; var output = input.reverse().match(regex)[0].reverse();
上一篇
非參與組:跨瀏覽器的混亂
下一篇
JavaScript 密碼驗證