जावा में रेगेक्स नामांकित समूह


173

यह मेरी समझ है कि java.regexपैकेज में नामित समूहों ( http://www. अनियमित-expressions.info/onym.html ) के लिए समर्थन नहीं है, तो क्या कोई मुझे तीसरे पक्ष के पुस्तकालय की ओर इशारा कर सकता है जो करता है?

मैंने jregex को देखा है, लेकिन इसकी आखिरी रिलीज 2002 में हुई थी और इसने मेरे लिए काम नहीं किया (वास्तव में मैंने केवल संक्षेप में कोशिश की थी) जावा 5 के तहत।


3
आपकी समझ गलत है। JDK7 नाम समूहों को संभालता है।
tchrist

2
@tchrist 2009 में JDK7 नहीं था।
एलेक्स .१

जवाबों:


275

( अपडेट : अगस्त 2011 )

जैसा कि उनके जवाब में जियोफलेन का उल्लेख है , जावा 7 अब नामित समूहों का समर्थन करता हैटिचर टिप्पणी में बताते हैं कि समर्थन सीमित है। वह अपने महान उत्तर " जावा रेगेक्स हेल्पर " में सीमाओं का विवरण देता है

सितंबर 2010 में ओरेकल के ब्लॉग में जावा 7 रेगेक्स नाम का ग्रुप सपोर्ट पेश किया गया था ।

जावा 7 की आधिकारिक रिलीज में, नामित कैप्चरिंग समूह का समर्थन करने के लिए निर्माण निम्नानुसार हैं:

  • (?<name>capturing text) एक नामित समूह "नाम" को परिभाषित करने के लिए
  • \k<name> एक नामित समूह "नाम" को पीछे हटाना
  • ${name} मिलानकर्ता के प्रतिस्थापन स्ट्रिंग में कैप्चर किए गए समूह के संदर्भ में
  • Matcher.group(String name) दिए गए "नामित समूह" द्वारा कैप्चर किए गए इनपुट बाद को वापस करने के लिए।

पूर्व जावा 7 के लिए अन्य विकल्प थे:


( मूल उत्तर : जनवरी 2009 , अगले दो लिंक अब टूट गए)

आप नामित समूह का उल्लेख नहीं कर सकते, जब तक कि आप रेगेक्स का अपना संस्करण कोड न करें ...

इस धागे में गोरबश 2 ने ठीक यही किया है ।

Regex2

(सीमित कार्यान्वयन, जैसा कि tchrist द्वारा फिर से बताया गया है , क्योंकि यह केवल ASCII पहचानकर्ताओं के लिए दिखता है। tchrist सीमा का विवरण देता है:

केवल एक ही नाम प्रति समूह में सक्षम होने के नाते (जिसे आप हमेशा नियंत्रण नहीं रखते हैं!) और उन्हें इन-रेगेक्स पुनरावृत्ति के लिए उपयोग करने में सक्षम नहीं किया जा रहा है।

ध्यान दें: आप पर्ल और पीसीआरई रेगेक्स में सही रेगेक्स रिकर्सन उदाहरण पा सकते हैं, जैसा कि रेगेक्सप पावर , पीसीआरई स्पेक्स और बैलेंसिंग पेरेंटेस स्लाइड के साथ मिलान स्ट्रिंग्स में वर्णित है )

उदाहरण:

स्ट्रिंग:

"TEST 123"

RegExp:

"(?<login>\\w+) (?<id>\\d+)"

पहुंच

matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login

बदलने के

matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____ 

(कार्यान्वयन से निकालें)

public final class Pattern
    implements java.io.Serializable
{
[...]
    /**
     * Parses a group and returns the head node of a set of nodes that process
     * the group. Sometimes a double return system is used where the tail is
     * returned in root.
     */
    private Node group0() {
        boolean capturingGroup = false;
        Node head = null;
        Node tail = null;
        int save = flags;
        root = null;
        int ch = next();
        if (ch == '?') {
            ch = skip();
            switch (ch) {

            case '<':   // (?<xxx)  look behind or group name
                ch = read();
                int start = cursor;
[...]
                // test forGroupName
                int startChar = ch;
                while(ASCII.isWord(ch) && ch != '>') ch=read();
                if(ch == '>'){
                    // valid group name
                    int len = cursor-start;
                    int[] newtemp = new int[2*(len) + 2];
                    //System.arraycopy(temp, start, newtemp, 0, len);
                    StringBuilder name = new StringBuilder();
                    for(int i = start; i< cursor; i++){
                        name.append((char)temp[i-1]);
                    }
                    // create Named group
                    head = createGroup(false);
                    ((GroupTail)root).name = name.toString();

                    capturingGroup = true;
                    tail = root;
                    head.next = expr(tail);
                    break;
                }

ऊपर दिए गए दोनों लिंक टूटे हुए लगते हैं?
जोनास

यह कोड छोटी गाड़ी है। यह ASCII पहचानकर्ताओं की तलाश में है। यह गलत है। यह कुछ भी है कि जावा एक पहचानकर्ता में अनुमति देता है की तलाश में होना चाहिए !!
tchrist

1
बस FYI करें क्योंकि आप इतने कर्तव्यनिष्ठ लगते हैं, सीमित भाग ASCII बनाम यूनिकोड नामों के बारे में इतना नहीं है क्योंकि यह केवल एक ही नाम के प्रति समूह का नाम रखने में सक्षम है (जिस पर आपका हमेशा नियंत्रण नहीं है!)। इन-रेगेक्स पुनरावृत्ति के लिए उनका उपयोग करने में सक्षम नहीं किया जा रहा है।
tchrist

@tchrist: इस परिशुद्धता (शामिल) के लिए धन्यवाद। मैंने "जावा रेगेक्स हेल्पर" (अपवोटेड) पर आपके तारकीय उत्तर के लिए एक लिंक भी जोड़ा है।
VonC

Java में Matcher object के लिए कोई matcher.name (int index) मेथड नहीं है ??
ot0


27

हाँ लेकिन इसकी गड़बड़ सूरज की कक्षाओं को हैक करने में है। एक सरल तरीका है:

http://code.google.com/p/named-regexp/

नामित- regexp मानक JDK नियमित अभिव्यक्ति कार्यान्वयन के लिए एक पतली आवरण है, जिसका नाम .net शैली में समूहों को संभालने के एकल उद्देश्य के साथ है: (? ...)।

इसका उपयोग जावा 5 और 6 के साथ किया जा सकता है (जेनरिक का उपयोग किया जाता है)।

Java 7 कैप्चरिंग ग्रुप्स नाम का हैंडल करेगा, इसलिए यह प्रोजेक्ट अंतिम नहीं है।


1
बहुत खराब इस कैंट का इस्तेमाल GWT के भीतर से किया जाता है।
सकुराबा

4
इस प्रोजेक्ट के GitHub कांटे को देखें, जो मूल से कई बग को ठीक करता है। यह मावेन सेंट्रल में भी होस्ट किया जाता है।
tony19

1
मेरे मामले में सावधानी का एक शब्द, जीथब पर tony19 कांटा एंड्रॉइड पर 0.1.8 के रूप में काम नहीं करता है।
चक डी।

2
@ रबरमाल्ट, एंड्रॉइड-विशिष्ट समस्या अब ठीक हो गई है और 0.1.9 में होगी।
tony19

2

आपको jregex से किस तरह की समस्या है ? इसने मेरे लिए java5 और java6 के तहत अच्छा काम किया।

Jregex तब तक अच्छी तरह से काम करता है (भले ही अंतिम संस्करण 2002 से हो), जब तक कि आप javaSE 7 का इंतजार नहीं करना चाहते


2

प्री-जावा 7 चलाने वालों के लिए, नामित समूहों को जोनी ( ओनिगुरुमा रीजेक्सप लाइब्रेरी का जावा पोर्ट ) द्वारा समर्थित किया जाता है । दस्तावेज़ीकरण विरल है, लेकिन इसने हमारे लिए अच्छा काम किया है।
बायनेर्स मावेन ( http://repository.codehaus.org/org/jruby/joni/joni/ ) के माध्यम से उपलब्ध हैं ।


ऊपर दिए गए रयान द्वारा बताए गए जोनी विकल्प में मुझे बहुत दिलचस्पी है - क्या आपके पास कैप्चर समूहों के नाम का उपयोग करने वाला कोई कोड स्निपेट है - मैं बुनियादी मिलान प्राप्त करने और सही ढंग से काम करने के लिए खोज करने में कामयाब रहा हूं - लेकिन मुझे नहीं लगता कि मैं किस पद्धति का उपयोग करूंगा समूह नाम तक पहुँच प्राप्त करें या समूह नाम का उपयोग करके कैप्चर का मान प्राप्त करें।
मल्स्मिथ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.