Обнаруживать, если источником является CSS/HTML/JavaScript

Я хочу использовать js beautify в каком-то источнике, но нет способа определить, какой тип источника он есть. Есть ли способ, грубый или нет, определить, является ли источник css, html, javascript или none?

Глядя на их сайт, у них есть это, похоже, что он выяснит, является ли это html:

function looks_like_html(source) {
    // <foo> - looks like html
    // <!--\nalert('foo!');\n--> - doesn't look like html
    var trimmed = source.replace(/^[ \t\n\r]+/, '');
    var comment_mark = '<' + '!-' + '-';
    return (trimmed && (trimmed.substring(0, 1) === '<' && trimmed.substring(0, 4) !== comment_mark));
}

просто нужно посмотреть, не css, javascript или нет. Это выполняется в node.js

Итак, этот код должен был бы сказать мне это JavaScript:

var foo = {
    bar : 'baz'
};

где, поскольку этот код должен сказать мне CSS:

.foo {
    background : red;
}

Таким образом, функция для проверки возвращает тип:

function getSourceType(source) {
    if (isJs) {
        return 'js';
    }
    if (isHtml) {
        return 'html';
    }
    if (isCss) {
        return 'css';
    }
}

Будут случаи, когда другие языки используются как Java, где мне нужно игнорировать, но для css/html/js. Я могу использовать украшатель.

Ответы

Ответ 1

Краткий ответ: практически невозможно.

- Благодаря вводу Катаны

Причина: допустимый HTML может содержать JS и CSS (и обычно это делается). JS может содержать как css, так и html (т.е.: var myContent = '<div> <style> CSS-Rules <script> JS Commands';). И даже CSS может содержать как комментарии.

Так что написать парсер для этого почти невозможно. Вы просто не можете их легко отделить.

Языки имеют правила о том, как их записывать, что вы хотите сделать, это обратное архивирование и проверить, применяются ли эти правила. Это, вероятно, не стоит усилий.


Подход 1

Если это требование стоит усилий, вы можете попробовать запустить разные синтаксические анализаторы в источнике и посмотреть, не ошибаются ли они. То есть Java, вероятно, не будет допустимым HTML/JS/CSS, но действительным Java-кодом (если он написан правильно).


Подход 2 - Благодаря вводу Bram

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

Пример

<code><div>This div is HTML var i=32;</div></code> 
<code>#thisiscss { margin: 0; padding: 0; }</code>
<code>.thisismorecss { border: 1px solid; background-color: #0044FF;}</code>
<code>function jsfunc(){ { var i = 1; i+=1;<br>}</code>

Синтаксический

$("code").each(function() {
    code = $(this).text();
   if (code.match(/<(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/)) {
      $(this).after("<span>This is HTML</span>");
   }
   else if (code.match(/(([ trn]*)([a-zA-Z-]*)([.#]{1,1})([a-zA-Z-]*)([ trn]*)+)([{]{1,1})((([ trn]*)([a-zA-Z-]*)([:]{1,1})((([ trn]*)([a-zA-Z-0-9#]*))+)[;]{1})*)([ trn]*)([}]{1,1})([ trn]*)/)) {
      $(this).after("<span>This is CSS</span>");
   }
   else {
      $(this).after("<span>This is JS</span>");
   }
});

Что он делает: проанализируйте текст.

HTML

Если он содержит символы типа '<' за которым следует br (или любой другой тег выше), а затем " > ", затем он html. (Включите проверку также, так как вы могли бы сравнивать числа и в js).

CSS

Если это сделано из имени шаблона (необязательно), за которым следует. или #, за которым следует id или класс, за которым следует {вы должны получить его отсюда... В вышеприведенном шаблоне я также включил возможные пробелы и вкладки.

JS

Иначе это JS.

Вы также можете сделать Regex как: Если он содержит '= {' или 'function...' или 'then JS. Также проверьте дополнительные регулярные выражения, чтобы более четко и/или предоставлять белые и черные списки (например, "var", но не "или" вокруг него ", функция (asdsd, asdsad) {assads} '..)

Bram Начните с того, что я продолжал:

$("code").each(function() {
   code = $(this).text();
   if (code.match(/^<[^>]+>/)) {
       $(this).after("<span>This is HTML</span>");
   }
   else if (code.match(/^(#|\.)?[^{]+{/)) {
     $(this).after("<span>This is CSS</span>");
   }
});

Для получения дополнительной информации:

http://regexone.com является хорошей ссылкой. Также проверьте http://www.sitepoint.com/jquery-basic-regex-selector-examples/ для вдохновения.

Ответ 2

Это зависит от того, разрешено ли вам смешивать языки, как указано в комментариях (т.е. иметь встроенные JS и CSS в вашем HTML), или если это отдельные файлы, которые вам необходимо обнаружить по какой-либо причине.

Строгим подходом было бы построить дерево из файла, где каждый node будет выражением (в Perl вы можете использовать HTML:: TreeBuilder). Затем вы можете проанализировать его и сравнить с исходным источником. Затем продолжайте, применяя исключение регулярных выражений для отсечения фрагментов кода и разбитых языков.

Другим способом было бы искать языковые шаблоны (я думал, что CSS использует только "* =" в некоторых ситуациях, поэтому, если у вас есть "=" сам по себе, должен быть JavaScript, встроенный или нет). Для HTML вы наверняка можете обнаружить теги с некоторым регулярным выражением, например

    if($source =~ m/(<.+>)/){}

В принципе, вам нужно будет учитывать некоторые причудливые случаи, например, если JavaScript используется для отображения некоторого кода HTML

    var code = "<body>";

Затем снова это зависит от ситуации, с которой вы сталкиваетесь, и того, как сочетаются коды.