我如何编写获取<script>标记内容的Java正则表达式?</script>

时间:2009-02-12 18:00:42

标签: java javascript regex gwt

我正在尝试将分析集成到我的GWT应用程序中。为此,我正在调用一个返回需要解析和评估的HTML字符串的服务。

我需要一个正则表达式来查找和获取标签的主体或2)“src”属性的内容。我想用JavaScript来评估这两个。我很高兴假设如果存在“src”属性,则可以忽略正文。

谢谢,

马特

6 个答案:

答案 0 :(得分:6)

一定是正则表达式吗?您可以使用DOM来获取此类信息,这里是获取BODY标记内容的一个简单示例,您可以将其应用于您喜欢的任何内容:

function test(){
    var body = document.getElementsByTagName("body")[0];
    alert(body.innerHTML);
}

答案 1 :(得分:2)

这似乎可以做你想要的:

    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这样的东西。

答案 2 :(得分:1)

您可以使用以下内容:

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

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

正则表达式使用惰性星形量词,并且在大多数情况下应该可以工作,但它肯定可以改进。

它将在$ 1中匹配脚本标记的属性,在$ 2中匹配正文。然后,您可以检查$ 1中的 src 属性(如果它不为空)。

答案 3 :(得分:0)

要匹配标记的正文,您可以尝试类似

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

您希望不区分大小写。假设在实际的脚本体中没有出现“”并且没有“&gt;”在标签的属性中。您可以将空白球体添加到正则表达式,以使其更加健壮。注意使用。*?确保扫描在第一个结束标记处停止。

要添加src属性,您可以尝试

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

并使用第二个子匹配来获取'src',然后使用第三个子匹配来获取正文。同样,您可能想要添加空白球体。

但最好通过正确的HTML / XML / SGML解析器运行该东西,因为在特殊情况下regexp会爆炸。

答案 4 :(得分:0)

怎么样

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

开头。您可能需要稍微自定义

  1. 使用单引号或不带引号接受src属性。
  2. 忽略'&lt; script'和'&gt;'
  3. 之间的白色

    您还必须使用DOTALL模式确保捕获换行符。

答案 5 :(得分:0)

感谢大家提出的所有好建议。我很快发现在GWT中使用Java的Regex API是不可能的,并且能够用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