不想释放Cthulhu,我决定(与我的其他答案不同)改为提供一个不尝试使用正则表达式解析 HTML 的问题的答案。相反,我转向了令人敬畏的力量,那就是 jQuery,并用它在客户端解析您的 HTML。
一个工作小提琴:http://jsfiddle.net/CKQ9f/6/
html:
<div id="wordwrapOriginal">Here is some code that I would like to wrap. Lets pretend this goes on for over 70 spaces.etend this g<b class="foo bar">Helloend this goes on for over 70 spaces.etend</b>Here is some code that I would like to wrap. Lets pretend this goes on for over 70 spaces.etend this g</div>
<hr>
<div id="wordwrapResult"></div>
jQuery:
// lifted from here: https://stackoverflow.com/a/5259788/808921
$.fn.outerHTML = function() {
$t = $(this);
if( "outerHTML" in $t[0] )
{ return $t[0].outerHTML; }
else
{
var content = $t.wrap('<div></div>').parent().html();
$t.unwrap();
return content;
}
}
// takes plain strings (no markup) and adds <br> to
// them when each "line" has exceeded the maxLineLen
function breakLines(text, maxLineLen, startOffset)
{
var returnVals = {'text' : text, finalOffset : startOffset + text.length};
if (text.length + startOffset > maxLineLen)
{
var wrappedWords = "";
var wordsArr = text.split(' ');
var lineLen = startOffset;
for (var i = 0; i < wordsArr.length; i++)
{
if (wordsArr[i].length + lineLen > maxLineLen)
{
wrappedWords += '<br>';
lineLen = 0;
}
wrappedWords += (wordsArr[i] + ' ');
lineLen += (wordsArr[i].length + 1);
}
returnVals['text'] = wrappedWords.replace(/\s$/, '');
returnVals['finalOffset'] = lineLen;
}
return returnVals;
}
// recursive function which will traverse the "tree" of HTML
// elements under the baseElem, until it finds plain text; at which
// point, it will use the above function to add newlines to that text
function wrapHTML(baseElem, maxLineLen, startOffset)
{
var returnString = "";
var currentOffset = startOffset;
$(baseElem).contents().each(function () {
if (! $(this).contents().length) // plain text
{
var tmp = breakLines($(this).text(), maxLineLen, currentOffset);
returnString += tmp['text'];
currentOffset = tmp['finalOffset'];
}
else // markup
{
var markup = $(this).clone();
var tmp = wrapHTML(this, maxLineLen, currentOffset);
markup.html(tmp['html']);
returnString += $(markup).outerHTML();
currentOffset = tmp['finalOffset'];
}
});
return {'html': returnString, 'finalOffset': currentOffset};
}
$(function () {
wrappedHTML = wrapHTML("#wordwrapOriginal", 70, 0);
$("#wordwrapResult").html(wrappedHTML['html']);
});
注意递归 - 不能用正则表达式做到这一点!