2013-06-19 10 views
7

जावा में मुझे <a> टैग्स को उस स्ट्रिंग में मिलान करने की आवश्यकता है जिसमें href विशेषता नहीं है। निम्न स्ट्रिंग में उदाहरण के लिए:<a> मिलान करने के लिए RegEx विशिष्ट विशेषता के बिना

text <a class="aClass" href="#">link1</a> text <a class="aClass" target="_blank">link2</a> text 

यह <a class="aClass" href="#">link1</a> (क्योंकि यह href शामिल हैं), लेकिन यह <a class="aClass" target="_blank">link2</a> से मेल खाना चाहिए (क्योंकि यह href शामिल नहीं है) से मेल नहीं करना चाहिए।

मैं अपने टैग मैच के लिए रेगुलर एक्सप्रेशन से निर्माण करने में कामयाब रहे:

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

लेकिन मैं समझ नहीं कैसे साथ टैग को खत्म करने href

(मैं जानता हूँ कि मैं HTML पारसर्स आदि का उपयोग कर सकते, लेकिन मैं जरूरत रेगुलर एक्सप्रेशन से साथ ऐसा करना।

+5

तुम क्यों regex का उपयोग करना चाहिए? [एचटीएमएल एक नियमित भाषा नहीं है] (http: // stackoverflow।com/प्रश्न/1732348/regex-मैच खुले टैग को छोड़कर-एक्सएचटीएमएल-संयमी-टैग/1732454 # 1732454)। –

+3

नियमित अभिव्यक्ति वाले HTML को पार्स करने के कई कारण हैं। कुछ संपादक खोज के लिए रेगेक्स अभिव्यक्ति के उपयोग की अनुमति देंगे और जहां एक ही संपादक "यहां अपना एचटीएमएल पार्सिंग कोड डालें" का समर्थन नहीं करता है। या बहुत बुरी तरह से स्वरूपित एचटीएमएल कोड से डेटा खींचने का प्रयास पार्सिंग त्रुटियों को फेंक सकता है। या होमवर्क असाइनमेंट ने रेगेक्स का उपयोग करने के लिए कहा और एक पार्सिंग इंजन नहीं। या क्या होगा यदि दस्तावेज़ एचटीएमएल भी नहीं था, इसके बजाय एचटीएमएल उदाहरण शामिल हैं ... सहमत हैं या असहमत हैं, एक इंजन के साथ एचटीएमएल पार्सिंग हमेशा सबसे अच्छा उपलब्ध समाधान नहीं है। –

+1

मुझे पूरा यकीन है कि लोग बॉट की तरह स्क्रिप्ट चला रहे हैं कि, जब भी "एचटीएमएल" और "रेगेक्स" दोनों शब्दों के साथ कोई सवाल होता है, तो वे स्वचालित रूप से उस लिंक को पोस्ट करते हैं * "आप [X] HTML को पार्स नहीं कर सकते regex के साथ ... "* जवाब। प्रफुल्लित। – acdcjunior

उत्तर

18

विवरण

<a[^>]* इन के रूप में की तरह regexs से सावधान रहें a जैसे <abbr> या <address> से शुरू होने वाले अन्य मान्य HTML टैग से भी मेल खाता है।

    : इसके अलावा बस स्ट्रिंग के अस्तित्व की तलाश में href के रूप में है कि स्ट्रिंग की तरह <a hreflang="en"...

    यह अभिव्यक्ति होगा एक और विशेषता का एक और विशेषता या <a class="thishrefstuff"... जैसे, या भाग के मूल्य के अंदर हो सकता है काफी अच्छा नहीं है

  • सभी एंकर टैग <a ... </a> से मेल खाता है जिसमें href विशेषता नहीं है।
  • यह लागू करेंगे टैग नाम a है और नहीं एक टैग जो केवल तरह <address>
  • उपेक्षा गुण जो भी सबस्ट्रिंग href वैध hreflang='en' या बना की तरह विशेषता का नाम में एम्बेड पत्र a साथ शुरू होता है Attributehref="some value"
  • bogus='href=""'

<a(?=\s|>)(?!(?:[^>=]|=(['"])(?:(?!\1).)*\1)*?\shref=['"])[^>]*>.*?<\/a>

enter image description here

विस्तारित

  • <a(?=\s|>) मैच खुला टैग की तरह सब ठीक से प्रारूपित विशेषताओं के मूल्य भाग के अंदर सभी पात्रों की उपेक्षा और बाद अगले सुनिश्चित टैग का नाम या तो एक स्थान या करीबी ब्रैकेट है, थाई नाम बलों a और बाकी नहीं कुछ होने
  • (?! आगे इस नकारात्मक नज़र शुरू करता है, तो हम इस टैग में एक href पाते हैं तो टैग के इस प्रकार टैग हम
    • (?: लिए देख रहे हैं नहीं है टैग के अंदर सभी पात्रों के माध्यम से स्थानांतरित करने के लिए
    • [^>=] मैच सभी गैर टैग समापन वर्ण जो टैग छोड़ने से regex इंजन से बचाता है गैर कैप्चर समूह, और गैर बराबर चिह्न जो आँख बंद करके जारी सभी पात्रों
    • | मिलान से इंजन से बचाता है शुरू या
    • =(['"]) एक खुले डबल या सिंगल कोट के बाद एक बराबर चिह्न से मेल खाता है। बोली समूह 2 इसलिए इसे सही ढंग से रखा जा सकता है बाद में
    • (?:(?!\1).)* मैच में कब्जा कर लिया है सभी पात्रों जो एक करीबी बोली कि खुले बोली
    • \1 मैच सही पास बोली
    • )*? गैर कब्जा बंद से मेल खाता नहीं हैं समूह और दोहराव जितनी बार आवश्यक हो उतनी बार
    • \shref=['"] वांछित href विशेषता से मेल खाने के लिए आवश्यक है। \s और =["'] सुनिश्चित करता है विशेषता नाम बस href है
    • ) नकारात्मक अग्रदर्शी बंद
  • [^>]*>.*?<\/a> मैच खुला से पूरी स्ट्रिंग बंद करने के लिए

जावा कोड उदाहरण:

इनपुट पाठ

<abbr>RADIO</abbr> text <a class="aClass" href="#">link1</a> text <a bogus='href=""' class="aClass" target="_blank">link2</a> text

कोड

आप एक की जगह समारोह में इसके उपयोग के तो गैर href-एंकर टैग हटाने के लिए बस कुछ नहीं के साथ सभी मैचों की जगह देख रहे हैं।

import java.util.regex.Pattern; 
import java.util.regex.Matcher; 
class Module1{ 
    public static void main(String[] asd){ 
    String sourcestring = "source string to match with pattern"; 
    Pattern re = Pattern.compile("<a(?=\\s|>)(?!(?:[^>=]|=(['\"])(?:(?!\\1).)*\\1)*?\\shref=['\"])[^>]*>.*?<\\/a> 
",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); 
    Matcher m = re.matcher(sourcestring); 
    int mIdx = 0; 
    while (m.find()){ 
     for(int groupIdx = 0; groupIdx < m.groupCount()+1; groupIdx++){ 
     System.out.println("[" + mIdx + "][" + groupIdx + "] = " + m.group(groupIdx)); 
     } 
     mIdx++; 
    } 
    } 
} 

मेल

$matches Array: 
(
    [0] => Array 
     (
      [0] => <a bogus='href=""' class="aClass" target="_blank">link2</a> 
     ) 

    [1] => Array 
     (
      [0] => 
     ) 

) 
+0

बिल्कुल सही जवाब। यह जो मैं करने की कोशिश कर रहा हूं उसके साथ यह बहुत अच्छा काम करता है। एकमात्र मुद्दा (किसी और के लिए) हो सकता है कि यदि उद्धरण के बिना कोई href विशेषता है, तो यह उससे मेल खाएगा। उदाहरण के लिए: '' – user2287359

4

मैं यह अजीब है कि आप चाहते हैं जरूरत यह regex के साथ क्या करना है, लेकिन आप एक नकारात्मक अग्रदर्शी का उपयोग कर सकते हैं।

<a(?![^>]+href).*?>(.*?)</a> 
+0

क्या मिलान टैग कई लाइनों पर फैलेगा? – Raedwald

+0

@ रेडवाल्ड यह –

-1

आपके पास एक विकल्प है जो पहले सभी टैग से मेल खाता है और उसके बाद उन लोगों से मेल खाने के लिए रेगेक्स का उपयोग करें ताकि आप उन्हें अनदेखा कर सकें। तो अपने छद्म कोड लगेगा जैसे:

<a>tags = html.find(all<a>tags); 
for(String <a>tag : <a>tags){ 
    if(<a>tag.isHref()) continue; 
    //do proccessing 
} 
+0

-1 के साथ कर सकता है ओपी ने निर्दिष्ट किया कि इसे रेगेक्स के साथ कैसे करें और एक HTML पार्सिंग इंजन नहीं। –

+0

@ डेनोमालेस इसका छद्म कोड ... एक HTML पार्सिंग इंजन नहीं। मैं कहीं भी एक पार्सर को लिंक या कहता हूं, मैं सिर्फ रेगेक्स के वैकल्पिक उपयोग का सुझाव देता हूं। –

0

मैं एक जावा विशेषज्ञ नहीं हूँ, लेकिन आप कुछ इस तरह की कोशिश कर सकते हैं:

String regex = new String("(?i)<a(?>[^h>]++|(?<!)h++|h++(?!ref\\s*+=))*>((?>[^<]++|<(?!/a>))*)</a>"); 
String replacement = new String("$1"); 
str.replaceAll(regex,replacement); 
संबंधित मुद्दे