检查字符串是否为 html

IT技术 javascript regex
2021-02-11 18:09:05

我有一个特定的字符串,我想检查它是否是 html。我正在使用正则表达式,但没有得到正确的结果。

我验证了我的正则表达式,它在这里工作正常

var htmlRegex = new RegExp("<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)</\1>");
return htmlRegex.test(testString);

这是小提琴,但正则表达式没有在那里运行。http://jsfiddle.net/wFWtc/

在我的机器上,代码运行良好,但结果是 false 而不是 true。这里缺少什么?

6个回答

用于检查字符串是否为 HTML 的更好的正则表达式是:

/^/

例如:

/^/.test('') // true
/^/.test('foo bar baz') //true
/^/.test('<p>fizz buzz</p>') //true

事实上,它非常好,它会true传递给它的每个字符串返回,这是因为每个字符串都是 HTML说真的,即使它的格式很差或无效,它仍然是 HTML。

如果您要查找的是 HTML 元素的存在,而不是简单的任何文本内容,您可以使用以下内容:

/<\/?[a-z][\s\S]*>/i.test()

它不会以任何方式帮助您解析 HTML,但它肯定会将字符串标记为包含 HTML 元素。

@clenemt,所以你认为a < b && a > c是 HTML?
2021-03-17 18:09:05
@zzzzBov 你知道你认为a<b && a>c是 HTML ......我希望 HTML 检测可以简化这么多。解析从来都不是一件容易的事。
2021-03-25 18:09:05
@oriadam,上下文用于检测这种情况下的元素。如果您使用a < b && a > c浏览器,会将><字符适当地转换为&gt;&lt;实体。相反,如果您使用a<b && a>c浏览器会将标记解释为a<b && a>c</b>因为缺少空格意味着<b打开一个<b>元素。这是我正在谈论的内容的快速演示
2021-04-01 18:09:05
这可能是我见过的投票最高的巨魔答案。;)
2021-04-01 18:09:05
老实说,我很惊讶我没有得到更多的反对票。
2021-04-10 18:09:05

方法#1这是测试字符串是否包含 HTML 数据的简单函数:

function isHTML(str) {
  var a = document.createElement('div');
  a.innerHTML = str;

  for (var c = a.childNodes, i = c.length; i--; ) {
    if (c[i].nodeType == 1) return true; 
  }

  return false;
}

这个想法是让浏览器 DOM 解析器决定提供的字符串是否看起来像 HTML。如您所见,它只是检查ELEMENT_NODE( nodeTypeof 1)。

我做了几个测试,看起来它有效:

isHTML('<a>this is a string</a>') // true
isHTML('this is a string')        // false
isHTML('this is a <b>string</b>') // true

此解决方案将正确检测 HTML 字符串,但是它有副作用 img/vide/etc. 一旦在innerHTML中解析,标签将开始下载资源。

方法#2另一种方法使用DOMParser并且没有加载资源的副作用:

function isHTML(str) {
  var doc = new DOMParser().parseFromString(str, "text/html");
  return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
}

注:
1.Array.from是 ES2015 方法,可以替换为[].slice.call(doc.body.childNodes).
2.some调用中的箭头函数可以替换为常用的匿名函数。

好主意,但接受的答案对性能不是更好吗?特别是如果你有很大的字符串(双关语)或者你必须经常使用这个测试。
2021-03-16 18:09:05
@JoseBrowne 即使它没有附加到 DOM?
2021-03-20 18:09:05
这是一个很棒的主意。但是,此函数无法检测结束标记(即isHTML("</a>") --> false)。
2021-04-09 18:09:05
很好的解决方案!.. 唯一的负面影响是,如果您的 html 包含任何静态资源,如图像 src 属性..innerHTML将强制浏览器开始获取这些资源。:(
2021-04-09 18:09:05
@kuus 是的,即使没有附加。使用 DOMParser 解决方案。
2021-04-10 18:09:05

一点点验证:

/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(htmlStringHere) 

这将搜索空标签(一些预定义的)和/终止的 XHTML 空标签,并由于空标签验证为 HTML 或将捕获标签名称并尝试在字符串中的某处找到它的结束标签以验证为 HTML。

解释演示:http : //regex101.com/r/cX0eP2

更新:

完成验证:

/<(br|basefont|hr|input|source|frame|param|area|meta|!--|col|link|option|base|img|wbr|!DOCTYPE).*?>|<(a|abbr|acronym|address|applet|article|aside|audio|b|bdi|bdo|big|blockquote|body|button|canvas|caption|center|cite|code|colgroup|command|datalist|dd|del|details|dfn|dialog|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frameset|head|header|hgroup|h1|h2|h3|h4|h5|h6|html|i|iframe|ins|kbd|keygen|label|legend|li|map|mark|menu|meter|nav|noframes|noscript|object|ol|optgroup|output|p|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video).*?<\/\2>/i.test(htmlStringHere) 

这会进行适当的验证,因为它包含所有HTML 标签,首先是空标签,然后是需要结束标签的其余标签。

在这里解释演示:http : //regex101.com/r/pE1mT5

请注意,底部正则表达式确实有效,但它不会检测未关闭的 html 标签,例如“'<strong>hello world”。授予这是损坏的 html 因此应该被视为一个字符串,但出于实际目的,您的应用程序可能也想检测这些。
2021-03-18 18:09:05
HTML 的设计考虑到了用户代理的宽恕。“无效”标签不是无效的,它们只是未知的,并且是允许的。“无效”属性并非无效……当开始涉及“Web 组件”和 JSX 等技术时,这一点尤其值得注意,这些技术混合了 HTML 和更丰富的组件描述,通常会生成影子 DOM。放在一个文件中并进行评估document.querySelector('strange')——它会起作用。
2021-03-20 18:09:05
(总而言之:由于规范的编写方式,尝试“验证”HTML 标记本质上是一个傻瓜的差事。提供给带有“无效”元素的示例 HTML 文档的链接,有一个100% 完全形成的,完整的 HTML 文档——从 1997 年开始——作为另一个例子。)
2021-03-28 18:09:05

上面zzzzBov 的回答很好,但它没有考虑杂散的结束标签,例如:

/<[a-z][\s\S]*>/i.test('foo </b> bar'); // false

一个也能捕获结束标签的版本可能是这样的:

/<[a-z/][\s\S]*>/i.test('foo </b> bar'); // true
本来可以更好地建议编辑,而不是将其作为评论发布。
2021-04-11 18:09:05
我想你的意思是<[a-z/][\s\S]*>- 注意第一组中的斜线。
2021-04-11 18:09:05

这是我不时使用的草率单线:

var isHTML = RegExp.prototype.test.bind(/(<([^>]+)>)/i);

它基本上会返回true包含<后跟ANYTHING后跟的字符串>

通过ANYTHING,我的意思基本上是除了空字符串之外的任何东西。

它不是很好,但它是一个单线。

用法

isHTML('Testing');               // false
isHTML('<p>Testing</p>');        // true
isHTML('<img src="hello.jpg">'); // true
isHTML('My < weird > string');   // true (caution!!!)
isHTML('<>');                    // false

正如您所看到的,它远非完美,但在某些情况下可能会为您完成这项工作。

正是我所需要的。没什么特别的,就是干净。谢谢!
2021-04-03 18:09:05