2011-03-28 6 views
47

मैं कुछ की तरह:संख्याओं के बजाय तर्क नामों के साथ संदेश कैसे प्रारूपित करें?

String text = "The user {0} has email address {1}." 
// params = { "Robert", "[email protected]" } 
String msg = MessageFormat.format(text, params); 

यह वही है में चला जाता है मेरे लिए महान नहीं है, क्योंकि कभी कभी मेरे अनुवादकों सुनिश्चित नहीं हैं, {0} और {1}, यह भी यह करने में सक्षम होना अच्छा होगा तर्कों के आदेश के बारे में चिंता किए बिना संदेशों को दोहराएं।

मैं संख्याओं के बजाय पठनीय नामों के साथ तर्कों को प्रतिस्थापित करना चाहता हूं। कुछ इस तरह:

String text = "The user {USERNAME} has email address {EMAILADDRESS}." 
// Map map = new HashMap(... [USERNAME="Robert", EMAILADDRESS="[email protected]"] 
String msg = MessageFormat.format(text, map); 

क्या ऐसा करने का कोई आसान तरीका है?

धन्यवाद! लूट

+2

कॉमन्स लैंग में StrSubstitutor – Ramon

+0

है, मैं गलत हो सकता हूं, लेकिन ऐसा लगता है कि [JTPL] (http://jtpl.sourceforge.net/) आपकी मदद कर सकता है। – Nishant

+0

संबंधित: http://stackoverflow.com/q/2286648/435605 –

उत्तर

26

आप इस के लिए MapFormat उपयोग कर सकते हैं: यह है कि मैं क्या उपयोग करें (main() समारोह सिर्फ परीक्षण कोड के लिए है)। यहाँ विवरण प्राप्त करें:

http://www.java2s.com/Code/Java/I18N/AtextformatsimilartoMessageFormatbutusingstringratherthannumerickeys.htm

String text = "The user {name} has email address {email}."; 
      Object[] params = { "nameRobert", "[email protected]" }; 
      Map map = new HashMap(); 
      map.put("name", "Robert"); 
      map.put("email", "[email protected]"); 

System.out.println("1st : " + MapFormat.format(text, map)); 

आउटपुट: 1: उपयोगकर्ता रॉबर्ट ई-मेल पता [email protected] है।

+3

हम इस वर्ग का प्रारूपण के लिए कितना आश्वस्त रूप से उपयोग कर सकते हैं? – Ketan

9

खुद को बनाना आसान है।

import java.util.HashMap; 
import java.util.Map; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class StringTemplate { 
    final private String template; 
    final private Matcher m; 
    static final private Pattern keyPattern = 
     Pattern.compile("\\$\\{([a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)*)\\}"); 
    private boolean blanknull=false; 

    public StringTemplate(String template) { 
     this.template=template; 
     this.m = keyPattern.matcher(template); 
    } 

    /** 
    * @param map substitution map 
    * @return substituted string 
    */ 
    public String substitute(Map<String, ? extends Object> map) 
    { 
     this.m.reset(); 
     StringBuffer sb = new StringBuffer(); 
     while (this.m.find()) 
     { 
      String k0 = this.m.group(); 
      String k = this.m.group(1); 
      Object vobj = map.get(k); 
      String v = (vobj == null) 
       ? (this.blanknull ? "" : k0) 
       : vobj.toString(); 
      this.m.appendReplacement(sb, Matcher.quoteReplacement(v)); 
     } 
     this.m.appendTail(sb); 
     return sb.toString();  
    } 

    public StringTemplate setBlankNull() 
    { 
     this.blanknull=true; 
     return this; 
    } 

    static public void main(String[] args) 
    { 
     StringTemplate t1 = new StringTemplate("${this} is a ${test} of the ${foo} bar=${bar} ${emergency.broadcasting.system}"); 
     t1.setBlankNull(); 
     Map<String, String> m = new HashMap<String, String>(); 
     m.put("this", "*This*"); 
     m.put("test", "*TEST*"); 
     m.put("foo", "$$$aaa\\\\111"); 
     m.put("emergency.broadcasting.system", "EBS"); 
     System.out.println(t1.substitute(m)); 
    } 
} 
1

आपका प्रश्न निकटता से संबंधित है: How to replace a set of tokens in a Java String आप velocity या अन्य टेम्पलेट लाइब्रेरी का उपयोग कर सकते हैं। लेकिन कुछ दर्द होगा क्योंकि जावा में किसी प्रकार का नक्शा अक्षर नहीं है।

1
static final Pattern REPLACE_PATTERN = Pattern.compile("\\x24\\x7B([a-zA-Z][\\w\\x2E].*?)\\x7D"); 

/** 
* Check for unresolved environment 
* 
* @param str 
* @return origin if all substitutions resolved 
*/ 
public static String checkReplacement(String str) { 
    Matcher matcher = REPLACE_PATTERN.matcher(str); 
    if (matcher.find()) { 
     throw LOG.getIllegalArgumentException("Environment variable '" + matcher.group(1) + "' is not defined"); 
    } 
    return str; 
} 

// replace in str ${key} to value 
public static String resolveReplacement(String str, Map<String, String> replacements) { 
    Matcher matcher = REPLACE_PATTERN.matcher(str); 
    while (matcher.find()) { 
     String value = replacements.get(matcher.group(1)); 
     if (value != null) { 
      str = matcher.replaceFirst(replaceWindowsSlash(value)); 
     } 
    } 
    return str; 
} 

लेकिन आप सभी प्रारूप विकल्प ढीला (जैसे ## #।)

16

देखें StrSubstitutororg.apache.commons.lang3 से:

Map valuesMap = HashMap(); 
valuesMap.put("animal", "quick brown fox"); 
valuesMap.put("target", "lazy dog"); 
String templateString = "The ${animal} jumped over the ${target}."; 
StrSubstitutor sub = new StrSubstitutor(valuesMap); 
String resolvedString = sub.replace(templateString); 

// resolvedString: "The quick brown fox jumped over the lazy dog." 
+0

कोई विचार यह कैसे हल करता है यदि उदाहरण के लिए लक्ष्य वैकल्पिक है और फिर आप मानचित्र में एक खाली स्ट्रिंग सेट करने के लिए $ {target} की बजाय खाली स्ट्रिंग रखना चाहते हैं? – poyger

+1

@ पोएजर ने यह कोशिश नहीं की, लेकिन आप शायद मैप किए गए कुंजियों के लिए 'null' के बदले '' ''' '' के बदले 'मानचित्र' को ओवरराइड कर सकते हैं। आज के रूप में –

+1

, 2018-02, इस वर्ग को कॉमन्स-टेक्स्ट में ले जाया गया है: https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/StrSubstitutor .html – Chris

1

मैं जानता हूँ कि मेरा उत्तर एक छोटे से देर से आता है, लेकिन अगर आप अभी भी जरूरत है यह कार्यक्षमता, एक पूर्ण टेम्पलेट इंजन डाउनलोड करने की आवश्यकता के बिना आप aleph-formatter (मैं लेखकों में से एक हूं) पर एक नज़र डाल सकता हूं:

Student student = new Student("Andrei", 30, "Male"); 

String studStr = template("#{id}\tName: #{st.getName}, Age: #{st.getAge}, Gender: #{st.getGender}") 
        .arg("id", 10) 
        .arg("st", student) 
        .format(); 
System.out.println(studStr); 

या आप तर्क श्रृंखला कर सकते हैं:

String result = template("#{x} + #{y} = #{z}") 
        .args("x", 5, "y", 10, "z", 15) 
        .format(); 
System.out.println(result); 

// Output: "5 + 10 = 15" 

आंतरिक यह द्वारा "पार्स करने" अभिव्यक्ति, कोई स्ट्रिंग संयोजन, regex/की जगह किया जाता है एक StringBuilder परिणाम बनाने का उपयोग कर काम करता है।

संबंधित मुद्दे

 संबंधित मुद्दे