जावा रेगेक्स टैग के बीच पाठ निकालने के लिए


82

मेरे पास कुछ कस्टम टैग के साथ एक फ़ाइल है और मैं टैग के बीच स्ट्रिंग निकालने के लिए एक नियमित अभिव्यक्ति लिखना चाहूंगा। उदाहरण के लिए यदि मेरा टैग है:

[customtag]String I want to extract[/customtag]

मैं टैग के बीच केवल स्ट्रिंग निकालने के लिए एक नियमित अभिव्यक्ति कैसे लिखूंगा। यह कोड सही दिशा में एक कदम की तरह लगता है:

Pattern p = Pattern.compile("[customtag](.+?)[/customtag]");
Matcher m = p.matcher("[customtag]String I want to extract[/customtag]");

निश्चित नहीं कि आगे क्या करना है। कोई विचार? धन्यवाद।


1
शुरुआत के लिए, आपको []स्क्वायर ब्रैकेट्स से बचने की जरूरत है जो एक रेगेक्स में मेटाचेचर हैं।
राइडर

जवाबों:


186

आप सही रास्ते पर हैं। अब आपको केवल वांछित समूह निकालने की जरूरत है, इस प्रकार है:

final Pattern pattern = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);
final Matcher matcher = pattern.matcher("<tag>String I want to extract</tag>");
matcher.find();
System.out.println(matcher.group(1)); // Prints String I want to extract

यदि आप कई हिट निकालना चाहते हैं, तो यह प्रयास करें:

public static void main(String[] args) {
    final String str = "<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear</tag>";
    System.out.println(Arrays.toString(getTagValues(str).toArray())); // Prints [apple, orange, pear]
}

private static final Pattern TAG_REGEX = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);

private static List<String> getTagValues(final String str) {
    final List<String> tagValues = new ArrayList<String>();
    final Matcher matcher = TAG_REGEX.matcher(str);
    while (matcher.find()) {
        tagValues.add(matcher.group(1));
    }
    return tagValues;
}

हालांकि, मैं मानता हूं कि नियमित अभिव्यक्ति यहां सबसे अच्छा जवाब नहीं है। मैं उन तत्वों को खोजने के लिए XPath का उपयोग करूंगा, जिनमें मेरी रुचि है। अधिक जानकारी के लिए Java XPath API देखें ।


3
बहुत बहुत धन्यवाद, यह वही है जो मुझे चाहिए था। मैं XPaths में देखूंगा, लेकिन अब मुझे लगता है कि यह समाधान काम करेगा। मेरे आवेदन बहुत सरल हैं और शायद इसी तरह रहेंगे। एक बार फिर धन्यवाद!
b10hazard

इस तार के बारे में क्या "<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear"? हम pearबिना नज़दीकी टैग के कैसे प्राप्त कर सकते हैं ?
K.Sopheak

सामान्यीकरण करने के लिए: निजी स्ट्रिंग extractDataFromTags (स्ट्रिंग टैग) {पैटर्न पैटर्न = Pattern.compile ("<<> +? (? +?)? </.+?>")। मिलान मिलानकर्ता = pattern.matcher (टैग); matcher.find (); वापसी (matcher.group (1)); // प्रिंट्स स्ट्रिंग मैं एक्सट्रेक्ट एक्सट्रैक्ट या थ्रो करना चाहता हूं}
पीएमटस

15

काफी ईमानदार होने के लिए, इस प्रकार के पार्सिंग के लिए नियमित अभिव्यक्ति सबसे अच्छा विचार नहीं है। आपके द्वारा पोस्ट की गई नियमित अभिव्यक्ति संभवतः सरल मामलों के लिए बहुत अच्छा काम करेगी, लेकिन अगर चीजें अधिक जटिल हो जाती हैं, तो आपको भारी समस्याएं होने का कारण होता है (इसी वजह से आप HTML को नियमित रूप से अभिव्यक्ति के साथ पार्स कर सकते हैं)। मुझे पता है कि आप शायद यह नहीं सुनना चाहते, मुझे पता है कि जब मैंने एक ही प्रकार के प्रश्न पूछे थे, लेकिन मैंने नहीं किया था, लेकिन स्ट्रिंग पार्सिंग मेरे लिए अधिक विश्वसनीय हो गई क्योंकि मैंने हर चीज के लिए नियमित अभिव्यक्ति का उपयोग करने की कोशिश करना बंद कर दिया।

jTopas एक AWESOME टोकन है जो हाथ से पार्सर्स लिखना काफी आसान बनाता है (I मानक रूप से मानक जावा स्कैनर / आदि .. पुस्तकालयों पर jtopas का सुझाव देता है)। यदि आप एक्शन में jtopas देखना चाहते हैं, तो यहां कुछ पार्सर हैं जिन्हें मैंने लिखा है jopopas का उपयोग करके इस प्रकार की फ़ाइल को पार्स करना

यदि आप XML फ़ाइलों को पार्स कर रहे हैं, तो आपको एक xml पार्सर लाइब्रेरी का उपयोग करना चाहिए। जब तक आप इसे केवल मज़े के लिए नहीं कर रहे हैं, तब तक आप ऐसा न करें, वहाँ से बाहर सिद्ध विकल्पों के बहुत सारे हैं


सलाह के लिये धन्यवाद। मैंने उन्हें बुकमार्क कर लिया है और मैं निश्चित रूप से भविष्य की परियोजनाओं में इसका उपयोग करूंगा। अभी के लिए रेगेक्स विधि शायद वह है जिसके साथ मैं जाऊंगा क्योंकि मैं जिस फ़ाइल को पार्स कर रहा हूं वह बहुत छोटी / सरल है।
1210 बजे b10hazard

7

टैग, विशेषता और मूल्य खोजने के लिए एक सामान्य, सरल और थोड़ा आदिम दृष्टिकोण

    Pattern pattern = Pattern.compile("<(\\w+)( +.+)*>((.*))</\\1>");
    System.out.println(pattern.matcher("<asd> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd TEST</asd>").find());
    System.out.println(pattern.matcher("<asd attr='3'> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd> <x>TEST<x>asd>").find());
    System.out.println("-------");
    Matcher matcher = pattern.matcher("<as x> TEST</as>");
    if (matcher.find()) {
        for (int i = 0; i <= matcher.groupCount(); i++) {
            System.out.println(i + ":" + matcher.group(i));
        }
    }

पैटर्न क्या होगा अगर वहाँ अलग टैग या की तरह नेस्टेड टैग का क्रम है <h2>Mac</h2><h1>loves it</h1>या <h2>Mac<h1>liked your answer</h1></h2>?
मैक

1
कृपया मुझे संपादित करें <matcher.groupCount (); से मैं <= matcher.groupCount (); पहला मिलान विकल्प शामिल करने के लिए यानी। 0 वें सूचकांक पर
AVA

4

इसे इस्तेमाल करे:

Pattern p = Pattern.compile(?<=\\<(any_tag)\\>)(\\s*.*\\s*)(?=\\<\\/(any_tag)\\>);
Matcher m = p.matcher(anyString);

उदाहरण के लिए:

String str = "<TR> <TD>1Q Ene</TD> <TD>3.08%</TD> </TR>";
Pattern p = Pattern.compile("(?<=\\<TD\\>)(\\s*.*\\s*)(?=\\<\\/TD\\>)");
Matcher m = p.matcher(str);
while(m.find()){
   Log.e("Regex"," Regex result: " + m.group())       
}

आउटपुट:

10 ईन

3.08%


2
    final Pattern pattern = Pattern.compile("tag\\](.+?)\\[/tag");
    final Matcher matcher = pattern.matcher("[tag]String I want to extract[/tag]");
    matcher.find();
    System.out.println(matcher.group(1));

टैग के लिए उपसर्ग के बारे में कैसे (यदि उपसर्ग गतिशील है)
user1514499

2
    String s = "<B><G>Test</G></B><C>Test1</C>";

    String pattern ="\\<(.+)\\>([^\\<\\>]+)\\<\\/\\1\\>";

       int count = 0;

        Pattern p = Pattern.compile(pattern);
        Matcher m =  p.matcher(s);
        while(m.find())
        {
            System.out.println(m.group(2));
            count++;
        }

1

मैं इस उत्तर को "आप एक्सएमएल को पार्स करने के लिए एक नियमित अभिव्यक्ति का उपयोग नहीं करना चाहिए" के साथ उपसर्ग करते हैं - यह केवल उन किनारे के मामलों में परिणाम देने वाला है जो सही काम नहीं करते हैं, और जब आप इसे ठीक करने की कोशिश करते हैं, तो हमेशा के लिए बढ़ती जटिलता । "

कहा जा रहा है, आपको स्ट्रिंग से मेल खाने और उस समूह को हथियाने की ज़रूरत है जिसे आप चाहते हैं:

if (m.matches())
{
   String result = m.group(1);
   // do something with result
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.