2013-10-01 64 views
0

我有一個正則表達式來獲取src和內容中存在的所有圖像的其餘屬性。屬性模式匹配器需要很長時間

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

如果我對匹配的內容就像是

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

查找(指數)掛,我看到線程轉儲

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) 

下面是否有解決方案或解決這個問題的解決方法?

+0

你不妨繼續之前閱讀http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454。 –

+0

http://stackoverflow.com/a/2408599/20938重複)永遠不要在正則表達式中使用'(。| \ s)'。只需指定DOTALL模式並單獨使用'.'。 –

+0

您示例中的屬性值缺少開頭引號。我希望這只是你在問題中引入的一個錯字。 –

回答

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")); 
} 
+0

我不是在尋找只是src。我也需要其他屬性(在src之前和之後)。例如。 altText user2836528

+0

輕鬆完成 - 請參閱更新 – Reimeus

0

它看起來像什麼你有是一個「evil regex」,這是並不少見,當你試圖建立一個複雜的正則表達式來匹配另一件事物(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'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)); 
      } 
     } 
    } 
} 
+0

我真的不知道這是一個「邪惡的正則表達式」。謹慎解釋?你可以看看這裏的一些調試輸出:http://regex101.com/r/wH4rD7/#debugger –

+0

我不是在尋找只是src。我也需要其他屬性(在src之前和之後)。例如。 altText user2836528

+0

如果你仔細看,Lindrian,我把上面的「邪惡的正則表達式」聯繫起來。這將解釋所有關於邪惡的正則表達式。至於你的第二個評論,你也可以在身體內部拉取任何你需要的東西。我的方法不僅可以工作,還可以更好地工作。我會更新我的答案,以表明如何獲得所有屬性。 –