2013-10-01 1 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», что не редкость, когда вы пытаетесь построить сложный regex, чтобы соответствовать одной вещи (src) внутри другой вещи (img). В частности, злые регулярные выражения обычно возникают, когда вы пытаетесь применить повторение к сложному подвыражению, которое вы делаете с (.|\s)*?.

Лучшим подходом было бы использовать два regexes; один для соответствия всем <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". Также отметим, что кванторы ленивы здесь (*? вместо того, чтобы просто *), это необходимо, чтобы предотвратить слишком много от потребляются

EDIT: хотя мой в 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

Если вы внимательно посмотрите, Линдриан, я связал «злое регулярное выражение» выше. Это объяснит все о злых регулярных выражениях. Что касается вашего второго комментария, вы также можете потянуть все, что вам нужно в теле. Мало того, что мой подход будет работать, он будет работать еще лучше. Я обновлю свой ответ, чтобы указать, как вы можете получить все атрибуты. –