2009-11-03 4 views
6

मेरे पास इस स्ट्रिंग में HTML का एक बड़ा हिस्सा है और मैं href = "..." से लिंक निकालने का प्रयास कर रहा हूं स्ट्रिंग का हिस्सा।जावा: मेरे पास HTML की एक बड़ी स्ट्रिंग है और href = "..." टेक्स्ट निकालने की आवश्यकता है

 String innerHTML = getHTML(); 
    Pattern p = Pattern.compile("href=\"(.*)\"", Pattern.DOTALL); 
    Matcher m = p.matcher(innerHTML); 
    if (m.find()) { 
    // Get all groups for this match 
    for (int i=0; i<=m.groupCount(); i++) { 
    String groupStr = m.group(i); 
    System.out.println(groupStr); 

    } 
    } 

कोई मुझे बता सकते हैं:

<a href="..." /> 
<a class="..." href="..." /> 

मैं वास्तव में regex के साथ लेकिन जब मैं निम्नलिखित कोड का उपयोग किसी कारण के लिए एक समस्या नहीं है: href निम्नलिखित रूपों में से एक में हो सकता है मेरे कोड में क्या गलत है? मैंने यह सामान php में किया था लेकिन जावा में मैं कुछ गलत कर रहा हूं ... क्या हो रहा है कि जब भी मैं इसे प्रिंट करने का प्रयास करता हूं तो यह पूरे HTML स्ट्रिंग को प्रिंट करता है ...

संपादित करें: बस इतना है कि हर कोई जानता है कि एक स्ट्रिंग मैं के साथ काम कर रहा हूँ की तरह:

<a class="Wrap" href="item.php?id=43241"><input type="button"> 
    <span class="chevron"></span> 
    </a> 
    <div class="menu"></div> 

हर मैं कोड चलाने के लिए, यह पूरी स्ट्रिंग प्रिंट ... यही समस्या है ...

और के बारे में jTidy का उपयोग कर ... मैं कर रहा हूँ इस पर यह जानना दिलचस्प होगा कि इस मामले में क्या गलत हुआ ...

+0

का उपयोग कर वास्तव में समस्या यह है क्या द्वारा यह है करना है? क्या आपको एक त्रुटि संदेश, या गलत परिणाम मिलता है? –

+0

ओह ... क्षमा करें ... पोस्ट अपडेट किया गया। लेकिन समस्या यह थी कि यह मुझे लिंक नहीं दे रहा था बल्कि फिर पूरी स्ट्रिंग को प्रिंट कर रहा था ... – Legend

+2

* "क्या कोई मुझे बता सकता है कि मेरे कोड में क्या गलत है?" * - हाँ; आप RegEx का उपयोग किसी ऐसे चीज़ के लिए करने का प्रयास कर रहे हैं जिसका उपयोग नहीं किया जाना चाहिए। एक HTML डोम पार्सर का उपयोग करें, जैसे कि जेटीडी (नीचे बलुस के उत्तर में लिंक)। –

उत्तर

8
.* 

यह एक लालची ऑपरेशन है जो उद्धरण सहित किसी भी चरित्र को ले जाएगा। जैसे

कोशिश कुछ:

"href=\"([^\"]*)\"" 
+0

यह अभी भी पूरी स्ट्रिंग को प्रिंट करता है और कैप्चर समूह नहीं :( – Legend

+1

शायद क्योंकि वह अस्वीकृत उद्धरण के बाद क्वांटिफ़ायर से चूक गया है। लेकिन फिर भी, इसके लिए RegEx का उपयोग करने का प्रयास करना बंद करें, यह नौकरी के लिए गलत उपकरण है! –

+0

लेकिन यह सबसे तेज़ है नौकरी के लिए उपकरण (विकास के अनुसार)। एचटीएमएल पार्सर्स दर्द हो सकता है। – Kugel

5

Regex महान लेकिन इस विशेष उद्देश्य के लिए सही उपकरण है। आम तौर पर आप इसके लिए एक स्टैक्सबेस पार्सर का उपयोग करना चाहते हैं। जावा एचटीएमएल पार्सर एपीआई की तरह jTidy पर एक नज़र डालें।

1

"href=\"(.*?)\"" भी काम करना चाहिए, लेकिन मुझे लगता है कि कुगेल का जवाब तेजी से काम करेगा।

सबसे पहले आपका रेगुलर एक्सप्रेशन में .* लालची है:

4

कोड द्वारा पोस्ट की गई साथ दो समस्याएं हैं। यह अंतिम " चरित्र तक पाया जा सकता है जब तक यह सभी पात्रों से मेल नहीं खा सकता है। आप इस मैच को .*? पर बदलकर गैर-लालची बना सकते हैं।

दूसरा, सभी मैचों को लेने के लिए, आपको समूहों की तलाश करने के बजाय Matcher.find के साथ पुनरावृत्त रखने की आवश्यकता है। समूह आपको रेगेक्स के प्रत्येक कोष्ठक अनुभाग तक पहुंच प्रदान करते हैं। हालांकि, आप हर बार नियमित नियमित अभिव्यक्ति मिलान के लिए देख रहे हैं।

Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.DOTALL); 
Matcher m = p.matcher(innerHTML); 

while (m.find()) 
{ 
    System.out.println(m.group(1)); 
} 
+0

यह भी काम करता है! धन्यवाद! – Legend

2

आप एक HTML पार्सर लाइब्रेरी का उपयोग हो सकता है:

एक साथ इन लाना आप निम्नलिखित कोड है जो आपको क्या चाहिए करना चाहिए देता है। उदाहरण के लिए jtidy आपको एचटीएमएल का एक डोम मॉडल देता है, जिसमें से आप सभी "ए" तत्वों को निकाल सकते हैं और अपनी "href" विशेषता

4

अंतर्निहित पार्सर का उपयोग करें।

EditorKit kit = new HTMLEditorKit(); 
    HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument(); 
    doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE); 
    kit.read(reader, doc, 0); 

    HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A); 

    while (it.isValid()) 
    { 
     SimpleAttributeSet s = (SimpleAttributeSet)it.getAttributes(); 
     String href = (String)s.getAttribute(HTML.Attribute.HREF); 
     System.out.println(href); 
     it.next(); 
    } 

या ParserCallback का उपयोग करें:: की तरह कुछ

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

public class ParserCallbackText extends HTMLEditorKit.ParserCallback 
{ 
    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos) 
    { 
     if (tag.equals(HTML.Tag.A)) 
     { 
      String href = (String)a.getAttribute(HTML.Attribute.HREF); 
      System.out.println(href); 
     } 
    } 

    public static void main(String[] args) 
     throws Exception 
    { 
     Reader reader = getReader(args[0]); 
     ParserCallbackText parser = new ParserCallbackText(); 
     new ParserDelegator().parse(reader, parser, true); 
    } 

    static Reader getReader(String uri) 
     throws IOException 
    { 
     // Retrieve from Internet. 
     if (uri.startsWith("http:")) 
     { 
      URLConnection conn = new URL(uri).openConnection(); 
      return new InputStreamReader(conn.getInputStream()); 
     } 
     // Retrieve from file. 
     else 
     { 
      return new FileReader(uri); 
     } 
    } 
} 

रीडर एक StringReader हो सकता है।

+0

इसके लिए धन्यवाद। इस दृष्टिकोण से अवगत नहीं था ... – Legend

3

एक और आसान और विश्वसनीय तरीके से Jsoup

Document doc = Jsoup.connect("http://example.com/").get(); 
Elements links = doc.select("a[href]"); 
for (Element link : links){ 
    System.out.println(link.attr("abs:href")); 
}