Проверьте, является ли строка html или нет


У меня есть определенная строка, для которой я хочу проверить, является ли она html или нет. Я использую регулярное выражение для того же, но не получая должного результата.

Я проверил мое регулярное выражение, и оно отлично работает здесь.

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

вот скрипка, но регулярное выражение там не работает. http://jsfiddle.net/wFWtc/

на моей машине код работает нормально, но в результате я получаю false вместо true. Чего здесь не хватает?

10 73

10 ответов:

лучше регулярное выражение, чтобы использовать, чтобы проверить, если строка является 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.

Способ #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 parser решить, выглядит ли предоставленная строка как HTML или нет. Как вы можете видеть, он просто проверяет ELEMENT_NODE (nodeType на 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 вызов можно заменить обычной анонимной функции.

немного проверки с помощью:

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

Это правильный проверки, так как он содержит все HTML-теги, сначала пустые, а затем остальные, которым нужен закрывающий тег.

объяснил демо здесь:http://regex101.com/r/pE1mT5

ответ zzzzBov выше хорошо, но это не учитывает случайные закрывающие теги, например:

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

версия, которая также ловит закрывающие теги, может быть такой:

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

если вы создаете регулярное выражение из строкового литерала, вам нужно избежать любых обратных косых черт:

var htmlRegex = new RegExp("<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)</\1>");
// extra backslash added here ---------------------^ and here -----^

это не обязательно, если вы используете литерал регулярных выражений, но тогда вам нужно бежать вперед косые черты:

var htmlRegex = /<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)<\/>/;
// forward slash escaped here ------------------------^

также ваш jsfiddle не работал, потому что вы назначили onload обработчик внутри другой onload обработчик-по умолчанию, как установлено в панели Framework & Extensions слева, нужно обернуть JS в onload. Измените это на параметр nowrap и исправьте строковый литерал экранируется, и он "работает" (в рамках ограничений, которые все указали в комментариях):http://jsfiddle.net/wFWtc/4/

насколько я знаю, регулярные выражения JavaScript не имеют обратных ссылок. Итак, эта часть вашего выражения:

</>

не будет работать в JS (но будет работать на некоторых других языках).

/<\/?[^>]*>/.test(str) только определить, содержит ли он HTML-теги, может быть xml

вот неаккуратно один-лайнер, который я использую время от времени:

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

он в основном вернется true для строк, содержащих < следовал по ANYTHING следовал по >.

By ANYTHING, Я имею в виду в основном все, кроме пустой строки.

это не здорово, но это один лайнер.

использование

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

как вы можете видеть, это далеко не идеально, но может сделать работа для вас в некоторых случаях.

С помощью jQuery:

function isHTML(str) {
  return /^<.*?>$/.test(str) && !!$(str)[0];
}

используя jQuery в этом случае, самая простая форма будет:

if ($(testString).length > 0)

Если $(testString).length = 1, это означает, что есть один HTML-тег внутри textStging.

все ответы здесь слишком инклюзивны, они просто ищут < следовал по >. Нет идеального способа определить, является ли строка HTML, но вы можете сделать это лучше.

ниже мы ищем закрывающие теги, и будет гораздо жестче и точнее:

import re
re_is_html = re.compile(r"(?:</[^<]+>)|(?:<[^<]+/>)")

и вот он в действии:

# Correctly identified as not HTML:
print re_is_html.search("Hello, World")
print re_is_html.search("This is less than <, this is greater than >.")
print re_is_html.search(" a < 3 && b > 3")
print re_is_html.search("<<Important Text>>")
print re_is_html.search("<a>")

# Correctly identified as HTML
print re_is_html.search("<a>Foo</a>")
print re_is_html.search("<input type='submit' value='Ok' />")
print re_is_html.search("<br/>")

# We don't handle, but could with more tweaking:
print re_is_html.search("<br>")
print re_is_html.search("Foo &amp; bar")
print re_is_html.search("<input type='submit' value='Ok'>")