0

我有一个正则表达式来获取内容中存在的所有图像的 src 和其余属性。

<img *((.|\s)*?) *src *= *['"]([^'"]*)['"] *((.|\s)*?) */*>

如果我匹配的内容就像

<img src=src1"/> <img src=src2"/>

find(index) 挂起,我在线程转储中看到以下内容

at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
    at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
    at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
    at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
    at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
    at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
    at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345) 

是否有解决此问题的解决方案或解决方法?

4

2 回答 2

1

一种解决方法是使用 HTML 解析器JSoup,例如

Document doc = 
      Jsoup.parse("<html><img src=\"src1\"/> <img src=\"src2\"/></html>");
Elements elements = doc.select("img[src]");
for (Element element: elements) {
    System.out.println(element.attr("src"));
    System.out.println(element.attr("alt"));
    System.out.println(element.attr("height"));
    System.out.println(element.attr("width"));
}
于 2013-10-01T21:33:51.067 回答
0

看起来您所拥有的是一个“邪恶的正则表达式”,当您尝试构建一个复杂的正则表达式以匹配另一事物 (img) 中的一个事物 (src) 时,这种情况并不少见。特别是,当您尝试对复杂的子表达式应用重复时,通常会发生邪恶的正则表达式,而您正在使用(.|\s)*?.

更好的方法是使用两个正则表达式;一个匹配所有<img>标签,然后另一个匹配其中的src属性。

我的 Java 生锈了,所以我只给你伪代码解决方案:

foreach( imgTag in input.match( /<img .*?>/ig ) ) {
    src = imgTag.match( /\bsrc *= *(['\"])(.*?)\1/i );
    // if you want to get other attributes, you can do that the same way:
    alt = imgTag.match( /\balt *= *(['\"])(.*?)\1/i );
    // even better, you can get all the attributes in one go:
    attrs = imgTag.match( /\b(\w+) *= *(['\"])(.*?)\2/g );
    // attrs is now an array where the first group is the attr name
    // (alt, height, width, src, etc.) and the second group is the
    // attr value
}

请注意使用反向引用来匹配适当类型的结束引号(即,这将匹配src='abc'and src="abc"。还请注意,量词在这里是惰性的(*?而不仅仅是*);这是防止消耗过多所必需的。

编辑:即使我的 Java 生锈了,我还是可以编写一个示例。这是Java中的解决方案:

import java.util.regex.*;

public class Regex {

    public static void main( String[] args ) {
        String input = "<img alt=\"altText\" src=\"src\" height=\"50\" width=\"50\"/> <img alt='another image' src=\"foo.jpg\" />";
        Pattern attrPat = Pattern.compile( "\\b(\\w+) *= *(['\"])(.*?)\\2" );
        Matcher imgMatcher = Pattern.compile( "<img .*?>" ).matcher( input );
        while( imgMatcher.find() ) {
            String imgTag = imgMatcher.group();
            System.out.println( imgTag );
            Matcher attrMatcher = attrPat.matcher( imgTag );
            while( attrMatcher.find() ) {
                String attr = attrMatcher.group(1);
                System.out.format( "\tattr: %s, value: %s\n", attrMatcher.group(1), attrMatcher.group(3) );
            }
        }
    }
}
于 2013-10-01T21:40:29.750 回答