Как бы я написал регулярное выражение Java, которое получает содержимое тега <script>? - PullRequest
4 голосов
/ 12 февраля 2009

Я пытаюсь интегрировать аналитику в мое приложение GWT. Для этого я вызываю сервис, который возвращает строку HTML, которую нужно проанализировать и проверить.

Мне нужно регулярное выражение, которое ищет и захватывает 1) тело тега или 2) содержимое атрибута "src". Я хочу оценить оба из них с помощью JavaScript. Я рад предположить, что если атрибут "src" существует, тело можно игнорировать.

Спасибо

Мэтт

Ответы [ 6 ]

6 голосов
/ 12 февраля 2009

Должно ли это быть регулярным выражением? Вы можете использовать DOM для получения такой информации, вот тривиальный пример получения содержимого тега BODY, вы можете применить его ко всему, что вам нравится:

function test(){
    var body = document.getElementsByTagName("body")[0];
    alert(body.innerHTML);
}
2 голосов
/ 12 февраля 2009

Это похоже на то, что вы хотите:

    final String srcOne = "<html>\r\n<head>\r\n<script src=\"http://test.com/some.js\"/>\r\n</head></html>";
    final String srcTwo = "<html>\r\n<head>\r\n<script src=\"http://test.com/some.js\"></script>\r\n</head></html>";
    final String tag = "<html>\r\n<head>\r\n<script>\r\nfunction() {\r\n\talert('hi');\r\n}\r\n</script>\r\n</head></html>";
    final String tagAndSrc = "<html>\r\n<head>\r\n<script src=\"http://test.com/some.js\">\r\nfunction() {\r\n\talert('hi');\r\n}\r\n</script>\r\n</head></html>";
    final String[] tests = new String[] {srcOne, srcTwo, tag, tagAndSrc, srcOne + srcTwo, tag + srcOne + tagAndSrc};

    final String regex = "<script(?:[^>]*src=['\"]([^'\"]*)['\"][^>]*>|[^>]*>([^<]*)</script>)";
    final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    for (int testNumber = 0; testNumber < tests.length; ++testNumber) {
        final String test = tests[testNumber];
        final Matcher matcher = pattern.matcher(test);
        System.out.println("--------------------------------");
        System.out.println("TEST " + testNumber + ": " + test);
        while (matcher.find()) {
            System.out.println("GROUP 1: " + matcher.group(1));
            System.out.println("GROUP 2: " + matcher.group(2));
        }
        System.out.println("--------------------------------");
        System.out.println();
    }

При этом вам, вероятно, будет лучше использовать что-то вроде Tag Soup , если это вообще возможно.

1 голос
/ 12 февраля 2009

Вы можете использовать что-то вроде этого:

</p> <pre><code>String ScriptPattern = "<script\b([^>]+)>(.*?)</script>" Pattern ScriptRegex = Pattern.compile(ScriptPattern, Pattern.CASE_INSENSITIVE);

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

Он будет соответствовать $ 1 атрибутам тега script, а $ 2 - телу. Затем вы можете проверить атрибут src в $ 1 (если он не пустой).

0 голосов
/ 12 февраля 2009

Спасибо всем за отличные предложения. Я быстро обнаружил, что невозможно использовать Java Regex API в GWT, и смог сделать то, что хотел с JSNI.

public static native String evalJS(Element e) /*-{
    var scripts = e.getElementsByTagName("script");

    for (i=0; i < scripts.length; i++) {
        // if src, eval it, otherwise eval the body
        if (scripts[i].hasAttribute("src")) {
            eval(scripts[i].getAttribute("src")); // silently fails here
        } else {
            eval(scripts[i].innerHTML); // this works
        }
    }
}-*/; 

К сожалению, я столкнулся с дополнительными проблемами, описанными в следующей ветке:

http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ac2589369ddec8a3

0 голосов
/ 12 февраля 2009

Как насчет

<script>(.*)</script>|<script src="(.*)">.*</script>

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

  1. принять атрибут src с одинарными или без кавычек.
  2. игнорировать белый цвет между ''

Вы также должны использовать режим DOTALL , чтобы . перехватывал строки.

0 голосов
/ 12 февраля 2009

Чтобы соответствовать телу тега, вы можете попробовать что-то вроде

<script[^>]*?>(.*?)</script>

, который вы хотите сопоставить без учета регистра. Работает, предполагая, что в текущем теле скрипта нет "", а в атрибутах тега нет ">". Вы можете добавить пробелы в регулярное выражение, чтобы сделать его более устойчивым. Обратите внимание на использование. *? чтобы убедиться, что сканирование останавливается на первом закрывающем теге.

Чтобы добавить атрибут src, вы можете попробовать

<script[^>]*?(src="([^"]*)")?[^>]*?>(.*?)</script>

и используйте второе совпадение, чтобы получить 'src', и третье, чтобы получить тело. Опять же, возможно, вы захотите добавить пробельные символы.

Но было бы лучше всего запустить его через надлежащий синтаксический анализатор HTML / XML / SGML, поскольку регулярные выражения в некоторых случаях могут взорваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...