2011-01-20 8 views
8

में पर्यावरण चर का विस्तार करें मैं जावा में पर्यावरण चर के प्रतिस्थापन करने के लिए एक फ़ंक्शन लिखने की कोशिश कर रहा हूं। तो अगर मैं एक स्ट्रिंग है कि इस तरह देखा था:टेक्स्ट

उपयोगकर्ता $ {USERNAME} के APPDATA पथ $ {APPDATA} है।

मैं परिणाम होना चाहते हैं: \ Users \ msmith \ AppData \ रोमिंग:

उपयोगकर्ता msmith के APPDATA पथ सी है।

अब तक मेरी टूट कार्यान्वयन इस तरह दिखता है:

public static String expandEnvVars(String text) {   
    Map<String, String> envMap = System.getenv(); 
    String pattern = "\\$\\{([A-Za-z0-9]+)\\}"; 
    Pattern expr = Pattern.compile(pattern); 
    Matcher matcher = expr.matcher(text); 
    if (matcher.matches()) { 
     for (int i = 1; i <= matcher.groupCount(); i++) { 
      String envValue = envMap.get(matcher.group(i).toUpperCase()); 
      if (envValue == null) { 
       envValue = ""; 
      } else { 
       envValue = envValue.replace("\\", "\\\\"); 
      } 
      Pattern subexpr = Pattern.compile("\\$\\{" + matcher.group(i) + "\\}"); 
      text = subexpr.matcher(text).replaceAll(envValue); 
     } 
    } 
    return text; 
} 

ऊपर नमूना पाठ, matcher.matches() रिटर्न झूठी का उपयोग करना। हालांकि अगर मेरा नमूना पाठ ${APPDATA} है तो यह काम करता है।

क्या कोई मदद कर सकता है?

उत्तर

8

आप matches() का उपयोग नहीं करना चाहते हैं। मिलान पूरे इनपुट स्ट्रिंग से मेल खाने का प्रयास करेंगे।

पैटर्न के खिलाफ पूरे क्षेत्र से मिलान करने का प्रयास।

आप क्या चाहते हैं while(matcher.find()) {। यह आपके पैटर्न के प्रत्येक उदाहरण से मेल खाएगा। find() के लिए प्रलेखन देखें।

प्रत्येक मैच के भीतर, group 0 हो जाएगा पूरे मिलान किया स्ट्रिंग (${appdata}) और group 1appdata हिस्सा होगा। जब तक आप कितना खरोंच से बातें निर्माण करने के लिए सीखने के लिए कोशिश कर रहे हैं

String pattern = "\\$\\{([A-Za-z0-9]+)\\}"; 
Pattern expr = Pattern.compile(pattern); 
Matcher matcher = expr.matcher(text); 
while (matcher.find()) { 
    String envValue = envMap.get(matcher.group(1).toUpperCase()); 
    if (envValue == null) { 
     envValue = ""; 
    } else { 
     envValue = envValue.replace("\\", "\\\\"); 
    } 
    Pattern subexpr = Pattern.compile(Pattern.quote(matcher.group(0))); 
    text = subexpr.matcher(text).replaceAll(envValue); 
} 
+1

यह काम करता है। धन्यवाद! –

+0

@ माइकल, आपका स्वागत है। – jjnguy

+0

matcher.group (0) के साथ आपका उदाहरण फेंकता है क्योंकि लौटाई गई स्ट्रिंग के $ {} भाग इस मामले के लिए बच निकले होंगे। इसलिए मैंने अभिव्यक्ति के लिए "\\ $ \\ {" + matcher.group (1) + "\\}" का उपयोग किया। –

0

, तुम सच में अपने स्वयं के टेम्पलेट इंजन को लागू नहीं परेशान - वहाँ multitudes already available हैं:

आपका अंतिम परिणाम कुछ ऐसा दिखाई देगा।

एक बहुत अच्छा एक FreeMaker है (जिसमें Java API है)। यहां एक ट्यूटोरियल है: http://www.bredelet.com/Denis/FreeMarker%20first%20steps.html,

+0

मुझे अभी अपाचे कॉमन्स org.apache.commons.exec.util.StringUtils.stringSubstitution() मिला है, यह वही करता है जो मैं चाहता हूं, और हम पहले से ही exec का उपयोग कर रहे हैं। –

10

मुझे लगता है कि आप पहले ही एक उत्तर स्वीकार कर चुके हैं। हालांकि, आप अपने लिए कोड लिखना नहीं चाहते हैं, अपाचे कॉमन्स लैंग लाइब्रेरी में StrSubstitutor नामक एक कक्षा है। यह वास्तव में यह करता है।

2
public static String expandEnvVars(String text) {   
    Map<String, String> envMap = System.getenv();  
    for (Entry<String, String> entry : envMap.entrySet()) { 
     String key = entry.getKey(); 
     String value = entry.getValue(); 
     text = text.replaceAll("\\$\\{" + key + "\\}", value); 
    } 
    return text; 
} 
+0

+1। यह पुस्तकालय की तुलना में अधिक कॉम्पैक्ट है। पथ के साथ खिड़कियों के नीचे काम करते समय मैं 'स्ट्रिंग मान = entry.getValue() पसंद करता हूं।प्रतिस्थापित करें ('\\', '/'); 'क्योंकि अन्य "\" char को बचने के रूप में व्याख्या किया जाता है जिसके परिणामस्वरूप अमान्य पथ – k3b

+0

होते हैं जबकि स्वीकृत समाधान काम करता है, यह एक अधिक कुशल है क्योंकि इसे उपयोग करने की आवश्यकता नहीं है नियमित अभिव्यक्ति। –

+1

@ डेव सी स्ट्रिंग # replaceAll हुड के नीचे नियमित अभिव्यक्तियों का उपयोग करता है – Bax