如何用正则从压缩后的HTML字符串中移除表格空行与空列?
移除压缩HTML字符串中表格的空行与空列
解决思路
直接用正则处理HTML容易因为嵌套标签、colspan等属性出错,最佳方案是借助浏览器的DOM解析能力,先把字符串转成DOM结构,再遍历表格处理空行和空列,最后转回压缩后的HTML字符串。
完整实现代码
let htmlString = ` <h2>lorem</h2><table style="width:100%"><tr><th>Company</th><th></th><th>Country</th></tr><tr><td>Alfreds Futterkiste</td><td></td><td>Germany</td></tr><tr><td>Centro comercial Moctezuma</td><td></td><td>Mexico</td></tr><tr><td></td><td></td><td></td></tr></table><p>Lorem ipsum dolor quas!</p><p>Lorem ipsum dolor</p> ` // complex example: let htmlString2 = ` <table><thead><tr><th><p>xyz</p></th><th></th><th><p><strong>2019</strong></p></th><th><p><strong>2018</strong></p></th><th></th></tr><tr><th></th><th></th><th><p><strong>xyz</strong></p></th><th colspan="2"><p><strong>xyz</strong></p></th></tr><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td><p><strong>x</strong></p></td><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td><p><strong>xyz</strong></p></td><td></td><td><p><strong>359,423</strong></p></td><td><p>349,380</p></td><td></td></tr></tbody></table> ` const removeEmptyColumnAndRow = (htmlString) => { // 创建DOM解析器 const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, 'text/html'); // 遍历所有表格 doc.querySelectorAll('table').forEach(table => { // 第一步:移除所有空行(所有单元格文本为空的行) const rows = Array.from(table.querySelectorAll('tr')); rows.forEach(row => { const cells = Array.from(row.querySelectorAll('th, td')); const isEmpty = cells.every(cell => cell.textContent.trim() === ''); if (isEmpty) row.remove(); }); // 获取处理空行后的有效行 const validRows = Array.from(table.querySelectorAll('tr')); if (validRows.length === 0) return; // 第二步:标记所有空列 // 先计算表格总列数(考虑colspan) let totalColumns = 0; validRows[0].querySelectorAll('th, td').forEach(cell => { totalColumns += parseInt(cell.getAttribute('colspan')) || 1; }); const columnIsEmpty = new Array(totalColumns).fill(true); // 遍历所有行,更新列的空状态 validRows.forEach(row => { let currentCol = 0; const cells = Array.from(row.querySelectorAll('th, td')); cells.forEach(cell => { const colspan = parseInt(cell.getAttribute('colspan')) || 1; // 只要单元格有内容,它覆盖的列都不为空 if (cell.textContent.trim() !== '') { for (let i = currentCol; i < currentCol + colspan; i++) { if (i < columnIsEmpty.length) columnIsEmpty[i] = false; } } currentCol += colspan; }); }); // 第三步:移除空列,同时调整colspan属性 validRows.forEach(row => { let currentCol = 0; const cells = Array.from(row.querySelectorAll('th, td')); const keepCells = []; cells.forEach(cell => { const colspan = parseInt(cell.getAttribute('colspan')) || 1; // 计算当前单元格覆盖的非空列数量 let nonEmptyCount = 0; for (let i = currentCol; i < currentCol + colspan; i++) { if (i < columnIsEmpty.length && !columnIsEmpty[i]) nonEmptyCount++; } // 有非空列则保留单元格,调整colspan if (nonEmptyCount > 0) { if (nonEmptyCount !== colspan) { cell.setAttribute('colspan', nonEmptyCount); } keepCells.push(cell); } currentCol += colspan; }); // 更新行内容 row.innerHTML = ''; keepCells.forEach(cell => row.appendChild(cell)); // 如果处理后行变为空,移除它 if (row.children.length === 0) row.remove(); }); }); // 将处理后的DOM转回压缩的HTML字符串 return doc.body.innerHTML.replace(/\s+/g, ''); } console.log(removeEmptyColumnAndRow(htmlString));
关键细节说明
- 空行判断:遍历行内所有
<th>和<td>,只有当所有单元格的文本内容(去除空格后)都为空时,才移除该行。 - 空列判断:考虑
colspan属性的影响,一个单元格可能覆盖多列,只要该单元格有内容,它覆盖的所有列都标记为非空。 - colspan调整:移除空列后,自动调整剩余单元格的
colspan值,保证表格结构不被破坏。 - 压缩输出:最后用正则替换掉所有空白字符,保持原HTML的压缩格式。
内容的提问来源于stack exchange,提问作者roi
相关产品推荐
相关产品推荐

