2009-11-15 3 views
1

Я буду первым, кто признает, что мое знание Regex безнадежно. Я использую Java со следующимиRegex для извлечения содержимого ссылки

Matcher m = Pattern.compile(">[^<>]*</a>").matcher(html); 
while (m.find()) { 
resp.getWriter().println(html.substring(m.start(), m.end())); 
} 

я получаю следующий список:

>Link Text a</a> 
>Link Text b</a> 

Что мне не хватает, чтобы удалить > и </a>.

Cheers.

+0

@Littlejon - Regex + HTML вопросы не очень популярны в наши дни. (Кстати, я не получаю в середине этого снова ... предыдущий был моим самым нисходящим ответом. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml самообъявленные теги) – Kobi

+0

@ Kobi - Итак, я видел. Но я только ищу фрагмент HTML. Также пытался использовать DOM без особого успеха. – Littlejon

+2

В качестве дополнения я полностью осознаю ограничения и полностью готов указать заряженный пистолет на мою собственную ногу :-) – Littlejon

ответ

2

Вы можете сделать это путем обертывания группы вокруг этой части вашего регулярного выражения, а затем с помощью group(X) где X является номером группы:

Matcher m = Pattern.compile(">([^<>]*)</a>").matcher(html); 
while (m.find()) { 
resp.getWriter().println(m.group(1)); 
} 

Но, лучше всего было бы использовать простой парсер для этого:

import java.io.*; 
import javax.swing.text.*; 
import javax.swing.text.html.*; 
import javax.swing.text.html.parser.*; 

public class HtmlParseDemo { 
    public static void main(String [] args) throws Exception { 
     Reader reader = new StringReader("foo <a href=\"#\">Link 1</a> bar <a href=\"#\">Link <b>2</b> more</a> baz"); 
     HTMLEditorKit.Parser parser = new ParserDelegator(); 
     parser.parse(reader, new LinkParser(), true); 
     reader.close(); 
    } 
} 

class LinkParser extends HTMLEditorKit.ParserCallback { 

    private boolean linkStarted = false; 
    private StringBuilder b = new StringBuilder(); 

    public void handleText(char[] data, int pos) { 
     if(linkStarted) b.append(new String(data)); 
    } 

    public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { 
     if(t == HTML.Tag.A) linkStarted = true; 
    } 

    public void handleEndTag(HTML.Tag t, int pos) { 
     if(t == HTML.Tag.A) { 
      linkStarted = false; 
      System.out.println(b); 
      b = new StringBuilder(); 
     } 
    } 
} 

Выход:

Link 1 
Link 2 more 
+0

Это сработало отлично. Благодарю. – Littlejon

+0

Добро пожаловать в Littlejon. –

+0

Могу ли я найти ссылку i.e '#' вместо Link 1 или Link 2? – Rites

2

Вы изучали использование capturing group?

Pattern.compile(">([^<>]*)</a>") 

Однако обратите внимание, что это вообще не рекомендуется использовать регулярные выражения для HTML, так как HTML не является регулярным. Вы получите более надежные результаты с помощью анализатора HTML, такого как JTidy.

+0

Я пробовал это. Предоставляет тот же список. Приветствия. – Littlejon

+0

Этот ответ также верен. Изменение html.substring (m.start(), m.end()) на m.group (1) делает эту работу. – Littlejon

2

Имейте ввиду, что из-за его ограниченного характера ваше регулярное выражение (и регулярное выражение вообще) может столкнуться с проблемами, если HTML, который вы пытаетесь проанализировать, немного сложнее. Например, следующий фрагмент не сможет правильно разобрать, но вполне правомочно (и общий) HTML:

<a href="blah.html">this is only a <em>single</em> link</a> 

Вы могли бы быть лучше, используя DOM парсер (я уверен, что Java имеет много вариантов в этом), затем вы можете запросить внутренний текст каждого тега <a>.

+1

nah, это не подведет, это просто не даст вам то, что вы ожидаете ..;) "> link" – falstro

1

Я опоздал на вечеринку, но я хотел бы отметить еще одну альтернативу:

(?<=X)  X, via zero-width positive lookbehind 

Если вы поместите ваш первоначальный > в этот беспорядок, т.е.

(?<=>)[^<>]*</a> 

, то он не должен быть возвращен как часть вашего результата.

Невеста, однако. Удачи!

0

Хороший быстрый способ проверить свои регулярные выражения, чтобы использовать редактор регулярных выражений, таких как следующее затмение плагин: http://brosinski.com/regex/

Смежные вопросы