CamelCase को java में camel_case में बदलने के लिए Rexx


86

मैं समझता हूं कि रेगेक्स का उपयोग करके स्ट्रिंग को परिवर्तित करने के लिए वांछित आउटपुट क्यों नहीं दिया FooBarगया है, Foo_Barजिसके बजाय देता है Foo_Bar_। मैं String.substring के साथ कुछ कर सकता था substring(0, string.length() - 2)या बस अंतिम चरित्र को बदल सकता था, लेकिन मुझे लगता है कि इस तरह के परिदृश्य का एक बेहतर समाधान है।

यहाँ कोड है:

String regex = "([A-Z][a-z]+)";
String replacement = "$1_";

"CamelCaseToSomethingElse".replaceAll(regex, replacement); 

/*
outputs: Camel_Case_To_Something_Else_
desired output: Camel_Case_To_Something_Else
*/

प्रश्न: वांछित आउटपुट प्राप्त करने के लिए एक neater तरीके की तलाश है?


जवाबों:


168

यह प्रश्न और अमरूद से देखेंCaseFormat

आपके मामले में, कुछ इस तरह:

CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "SomeInput");

@eliocs प्रश्न को एंड्रॉइड और "एनटर तरीका" टैग नहीं किया गया था .. वैसे भी

2
CaseFormat लिंक ऑफ़लाइन है। रिप्लेसमेंट यहां है
एंटीकॉम

66

निचले मामले और ऊपरी मामले को दो समूह के रूप में बांधें, यह ठीक होगा

public  class Main
{
    public static void main(String args[])
    {
        String regex = "([a-z])([A-Z]+)";
        String replacement = "$1_$2";
        System.out.println("CamelCaseToSomethingElse"
                           .replaceAll(regex, replacement)
                           .toLowerCase());
    }
}

2
नोट: यदि इनपुट स्ट्रिंग में एकल अक्षर शब्दों की अनुमति है, जैसे "thisIsATest", तो उपरोक्त कोड "this_is_atest" प्रिंट करेगा। अमरूद, स्वीकृत उत्तर में, "this_is_a_test" में परिणाम देता है।
DtotheK

यह एक कैप के साथ शुरू होने वाले नाम पर काम नहीं करेगा, जैसे IBMIsMyCompany:।
यूजर 3301

37

आप नीचे कोड स्निपेट का उपयोग कर सकते हैं:

String replaceAll = key.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();

क्या होगा यदि मेरे स्ट्रिंग में एक नंबर है - मोड 3 मोड 3 के रूप में समाप्त होता है, जबकि मैं मोड_3 चाहता हूं।
माइक स्टोडार्ड

यह ऊंट मामले MyUUIDको ठीक से अंडरस्कोर की तरह परिवर्तित नहीं करता है, मुझे मिला my_uu_id
User3301

6

मैं RegEx प्रदान नहीं कर सकता, यह वैसे भी पागलपनपूर्ण होगा।

इस फ़ंक्शन को स्वचालित जिम की मान्यता के साथ आज़माएं।

दुर्भाग्यवश अमरूद का उपरी तौर पर ऊपरी मामले के सारांशों का पता नहीं लगता है, इसलिए "bigCAT" को "BIG_C__T_T" में बदल दिया जाएगा

/**
 * Convert to UPPER_UNDERSCORE format detecting upper case acronyms
 */
private String upperUnderscoreWithAcronyms(String name) {
    StringBuffer result = new StringBuffer();
    boolean begin = true;
    boolean lastUppercase = false;
    for( int i=0; i < name.length(); i++ ) {
        char ch = name.charAt(i);
        if( Character.isUpperCase(ch) ) {
            // is start?
            if( begin ) {
                result.append(ch);
            } else {
                if( lastUppercase ) {
                    // test if end of acronym
                    if( i+1<name.length() ) {
                        char next = name.charAt(i+1);
                        if( Character.isUpperCase(next) ) {
                            // acronym continues
                            result.append(ch);
                        } else {
                            // end of acronym
                            result.append('_').append(ch);
                        }
                    } else {
                        // acronym continues
                        result.append(ch);
                    }
                } else {
                    // last was lowercase, insert _
                    result.append('_').append(ch);
                }
            }
            lastUppercase=true;
        } else {
            result.append(Character.toUpperCase(ch));
            lastUppercase=false;
        }
        begin=false;
    }
    return result.toString();
}

4

बस लाइन की शुरुआत के रूप में क्यों नहीं पूर्व चरित्र से मेल खाते हैं $?

String text = "CamelCaseToSomethingElse";
System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "$1_$2"));

ध्यान दें कि यह संस्करण उस चीज़ पर किया जाना सुरक्षित है जो पहले से ऊंट आवरण है।


आप का उपयोग करने की कोशिश कर रहे हैं ^और $एंकर के रूप में? क्योंकि उनका अर्थ तब बदल जाता है जब आप उन्हें चरित्र वर्ग में रखते हैं। [^$_A-Z]किसी भी चरित्र है कि नहीं है से मेल खाता है $, _या एक अपरकेस अक्षर, और मुझे लगता है कि आप क्या मतलब है नहीं लगता।
एलन मूर

एंकर के रूप में इरादा नहीं, ऊपरी चरित्र से मेल नहीं खाने का प्रयास कर रहा हूँ, $गलती से जोड़ा गया था क्योंकि यह एक तकनीक है जिसका उपयोग मैं क्लास-नामों पर करता हूं।
ब्रेट रायन

3

शून्य-चौड़ाई वाला लुकअप अभिकथन जोड़ें।

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

(?=X)आदि के लिए प्रलेखन पढ़ें ।

व्यक्तिगत रूप से, मैं वास्तव में स्ट्रिंग को विभाजित करूंगा , फिर इसे फिर से जोड़ूंगा। यह सही होने पर भी तेज हो सकता है, और यह नियमित अभिव्यक्ति जादू की तुलना में कोड को समझने में बहुत आसान बनाता है। मुझे गलत मत समझो: मुझे नियमित अभिव्यक्ति पसंद है। लेकिन यह वास्तव में एक स्वच्छ नियमित अभिव्यक्ति नहीं है, न ही यह परिवर्तन एक क्लासिक रेगेक्स कार्य है। आखिर ऐसा लगता है कि आप भी लोअरकेस करना चाहते हैं?

एक बदसूरत लेकिन त्वरित हैक के (.)([A-Z]+)साथ प्रतिस्थापित करना होगा $1_$2और फिर बाद में पूरे स्ट्रिंग को कम करना होगा (जब तक कि आप पर्ल-एक्सट्रेक्टेड रेगेक्स नहीं कर सकते, जहां आप सीधे प्रतिस्थापन को कम कर सकते हैं!)। फिर भी मैं निचले-से-ऊपरी संक्रमण में विभाजित होने पर विचार करता हूं, फिर रूपांतरण करता हूं, फिर ऐसा करने का उचित और सबसे पठनीय तरीका है।


हां, आखिरकार मैं चाहूंगा कि यह लोअर केस में भी हो।
अंजमार्टिन

इसलिए मैं इसे चंक्स मिलान में विभाजित करूँगा [A-Z][a-z]*, पहला अक्षर नीचे करूँगा , और उन्हें फिर से जोड़ूँगा। या प्रतिस्थापन + लोअरकेस चाल मैं सिर्फ मुख्य उत्तर में जोड़ा गया।
QUIT - अनोनी-मूस

2
public class ReplaceFromCameltoSnake {
    public static void main(String args[]){
        String s1=" totalAmountWithoutDiscount";  
        String replaceString=s1.replaceAll("([A-Z]+)","\\_$1").toLowerCase(); 
        System.out.println(replaceString);  
    }
}

$ 1-का उपयोग समूह बनाने के लिए किया जाता है
abinash sahu

2

यकीन नहीं है कि शुद्ध रेगेक्स के साथ वास्तव में कुछ ठोस होना संभव है। विशेष रूप से समरूपों का समर्थन करने के लिए।

मैंने @radzimir उत्तर से प्रेरित होकर एक छोटा सा कार्य किया है, जो समरूपता और वर्णमाला वर्ण का समर्थन नहीं करता है:

से https://gist.github.com/ebuildy/cf46a09b1ac43eea17c7621b7617ebcd :

private static String snakeCaseFormat(String name) {
    final StringBuilder result = new StringBuilder();

    boolean lastUppercase = false;

    for (int i = 0; i < name.length(); i++) {
        char ch = name.charAt(i);
        char lastEntry = i == 0 ? 'X' : result.charAt(result.length() - 1);
        if (ch == ' ' || ch == '_' || ch == '-' || ch == '.') {
            lastUppercase = false;

            if (lastEntry == '_') {
                continue;
            } else {
                ch = '_';
            }
        } else if (Character.isUpperCase(ch)) {
            ch = Character.toLowerCase(ch);
            // is start?
            if (i > 0) {
                if (lastUppercase) {
                    // test if end of acronym
                    if (i + 1 < name.length()) {
                        char next = name.charAt(i + 1);
                        if (!Character.isUpperCase(next) && Character.isAlphabetic(next)) {
                            // end of acronym
                            if (lastEntry != '_') {
                                result.append('_');
                            }
                        }
                    }
                } else {
                    // last was lowercase, insert _
                    if (lastEntry != '_') {
                        result.append('_');
                    }
                }
            }
            lastUppercase = true;
        } else {
            lastUppercase = false;
        }

        result.append(ch);
    }
    return result.toString();
}

1
यह एक गुणवत्ता का जवाब है, यह ज्यादातर किनारे के मामलों को संभालता है।
यूजर 3301

1
([A-Z][a-z\d]+)(?=([A-Z][a-z\d]+))

एक बड़े अक्षर की खोज करनी चाहिए, उसके बाद अक्षरों को कम करना चाहिए। सकारात्मक लुकहेड एक और अक्षर के लिए एक बड़े अक्षर से शुरू होता है, उसके बाद अक्षरों को छोटा किया जाता है, लेकिन इसे मैच में शामिल नहीं किया जाएगा।

यहां देखें: http://regexr.com?30ooo


0

मुझे ऊंट केस प्रारूप में कुछ कुंजियों को अंडरस्कोर के साथ कम केस में बदलने के लिए इसे लागू करना पड़ा है। नियमित अभिव्यक्ति मैं आया हूँ:

(?<!^|_|[A-Z])([A-Z])

अंग्रेजी में यह कैपिटल लेटर के लिए है, जो स्ट्रिंग की शुरुआत, अंडरस्कोर या किसी अन्य कैपिटल लेटर से पहले नहीं है

नीचे दिए गए नमूनों में, बोल्ड में पात्र वही हैं जो पूर्वोक्त नियमित अभिव्यक्ति का उपयोग करके एक मैच का निर्माण करें।

  • ऊंट सी ase टीएस चूकना lse
  • ऊंट सी ase टीएस चूकना lse
  • camel_case_to_something_else
  • Camel_Case_To_Something_Else
  • CAMEL_CASE_TO_SOMETHING_ELSE

ध्यान दें कि अभिव्यक्ति स्ट्रिंग को प्रभावित नहीं करती है जो पहले से ही निचले मामले में हैं + अंडरस्कोर प्रारूप।

प्रतिस्थापन पैटर्न होगा:

_l$1

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

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