解析html格式的字符串中有几个html元素,并统计各个元素的个数

题目

解析html格式的字符串中有几个html元素,并统计各个元素的个数,字符串如下

let a = `
<body>
    <script type="module" src="strings.m.js"></script>
    <cr-most-visited visible_=""></cr-most-visited>
    <script type="module" src="new_tab_page_third_party.js"></script>
    <button>button</button>
    <input type="text" />
    <div id="main-content" class="page-content" style="display: block;">
        <div class="page-title">
            <h1 class="page-title-text">New Tab</h1>
        </div>
    </div>
</body>
`

解答方法有三种,分别为

  • 转化成dom树,然后根据树结构进行深度遍历统计元素个数
  • 正则匹配
  • 字符串 indexOf 查找元素符号 “<” 和 “>”

解法1

转化成 dom 树后进行深度遍历

// ...
let div = document.createElement("div")
div.innerHTML = a

function find(nodes) {
  Array.prototype.forEach.call(nodes, n => {
    if (n.nodeType === 1) {
      if (map[n.nodeName]) {
        map[n.localName] ++
      } else {
        map[n.localName] = 0
      }
      find(n.childNodes)
    }
  })
}

let map = {}
find(div.childNodes)
div = null
console.log(map)

解法2

使用正则

// ...
let tags = a.match(/<\/\w+>|<[^<^>]*\/>/g) // 使用正则表达式匹配所有的HTML标签
let tagCount = {} // 用于存储每个标签的数量

if (tags) {
  // 如果找到了标签
  tags.forEach(tag => {
    let name
    if (tag.startsWith('</')) {
      name = tag.match(/<\/(\w+)>/)[1]
    } else {
      name = tag.match(/<(\w+).*\/>/)[1]
    }
    if (tagCount[name]) {
      // 如果已经统计过这个标签,增加数量
      tagCount[name]++
    } else {
      // 否则,初始化这个标签的数量
      tagCount[name] = 1
    }
  })
}
console.log(tagCount) // 输出各个标签的数量

解法3 (推荐)

字符串 indexOf 查找元素符号 “<” 和 “>”

// ...

function main(string) {
  let start, end
  let str = string
  let map  = {}
  while((start = str.indexOf('<')) > -1) {
    if (str[start + 1] === '/') {
      str = str.slice(start + 2)
      continue
    }
    end = str.indexOf('>')
    if (end < start) {
      str = str.slice(start)
      continue
    }
    if (end > -1) {
      let tag = str.slice(start + 1, end)
      tag = tag.split(' ')[0]
      if (map[tag]) {
        map[tag]++
      } else {
        map[tag] = 1
      }
      str = str.slice(end + 1)
    } else {
      break
    }
  }
  return map
}
console.log(main(a))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值