js匹配标签

我想从html字符串中匹配出span标签且它的class类中有editor-var这个类名,正则应该怎么写哦, 写了半天没写出来

阅读 3.5k
5 个回答

感谢各位老铁, 可能我需求没说明白, 我是要匹配指定的标签然后去修改它的一个属性, 目前已经找到解决方法了;先将html字符串转成文档片段下的真实DOM, 然后通过选择器去批量修改查到的节点属性, 然后再转成html字符串

优化@leftstick的,不匹配editor-var2222aaaaeditor-var2222这种

var str = `
  你好
  <span class="editor-var">想要的1</span>
  <span class="editor-var2">不要</span>
  <span class="aaeditor-var">不要</span>
  你好
  <span class="editor-var active">想要的2</span>
  <span class="abc editor-var active">想要的3</span>
`;

const list = str.match(/<span.*?\sclass=".*\beditor-var\b.*?".*>.*?<\/span>/g)
console.log('list', list)

给你个粗暴的:

const html = `<div>
<span>asdf</span>
<span class="editor-var">hello</span>
<span class="name editor-var wrong">fuck</span>
</div>`;

const matched = html.match(/(<span.*class=".*editor-var.*".*>.*<\/span>)/g);

/**
 * [
 *  '<span class="editor-var">hello</span>',
 *  '<span class="name editor-var wrong">fuck</span>'
 * ]
 */
console.log(matched);

它很挫,请疯狂优化它

let string= `
  你好
  <span class="editor-var">想要的1</span>
  <span class="editor-var2">不要</span>
  <span class="aaeditor-var">不要</span>
  你好
  <span class="editor-var active">想要的2</span>
  <span class="abc editor-var active">想要的3</span>
`;
let reg = /<span[^>]*\s+class="[^"]*\beditor-var\b[^>]*">.*<\/span>/g;
console.log(string.match(reg));

这种问题如果想要完美匹配的话,只用正则是无法满足的,必须要词法分析才行。
自己实现也比较复杂,因为html可能缺少闭合标签,属性可能缺少引号,属性名是大小写不敏感的,或者其中有换行等等。
所以建议用现成的库来分析,比如parse5posthtml-parserhyntaxhtmlparser2等。

例子:使用parse5解析
import { parseFragment, serialize } from "parse5";

/**
 * @param {string} code
 * @param {string} className
 * @return {Array<string>}
 */
function findHTMLSpanElementWithClassName (code, className) {
  const result = [];

  const nodes = [parseFragment(code)];
  for (const node of nodes) {
    if (
      "span" === node.nodeName &&
      node.attrs.some(
        attr =>
          "class" === attr.name &&
          attr.value.split(/\s+/).includes(className),
      )
    ) {
      result.push(node);
    }

    if (Array.isArray(node.childNodes)) {
      nodes.push(...node.childNodes);
    }
  }

  return result.map(
    node =>
      serialize({
        nodeName: '#document-fragment',
        childNodes: [node],
      }),
  );
}
推荐问题