জাভাতে স্ট্রিং প্রতিস্থাপন, একটি বেগ টেমপ্লেটের অনুরূপ


98

Stringজাভাতে কোনও প্রতিস্থাপন প্রক্রিয়া আছে, যেখানে আমি কোনও পাঠ্য সহ বস্তুগুলি পাস করতে পারি এবং এটি স্ট্রিংয়ের পরিবর্তে এটি ঘটে ces
উদাহরণস্বরূপ, পাঠ্যটি হ'ল:

Hello ${user.name},
    Welcome to ${site.name}. 

আমার যে জিনিসগুলি রয়েছে তা হ'ল "user"এবং "site"। আমি প্রদত্ত স্ট্রিংগুলিকে ${}বস্তুগুলি থেকে এর সমতুল্য মান দিয়ে প্রতিস্থাপন করতে চাই । এটি আমরা বেগের টেম্পলেটে বস্তুর প্রতিস্থাপনের মতোই।


4
কোথায় প্রতিস্থাপন? একটি শ্রেণী? একটি জেএসপি? String.format("Hello %s", username);
স্ট্রিংয়ের

4
@ দ্রু: উদাহরণস্বরূপ, স্ট্রিংটি পছন্দ মতো Hello ${user.name}, পছন্দ নয় Hello %sবা Hello {0}
আদিল আনসারী

4
আপনার যদি এমন কিছু প্রয়োজন হয় যা বেগের মতো দেখায় এবং গতির মতো গন্ধ পায়, তবে এটি বেগ? :)
সার্জ

@ দ্রু: এটি কোনও শ্রেণি নয়। আমি উপরের পাঠ্যটি একটি "স্ট্রিং" ভেরিয়েবলে রেখেছি এবং objects {inside এর মধ্যে স্ট্রিংয়ের সমস্ত উপস্থিতি সংশ্লিষ্ট বস্তুর মানগুলির সাথে প্রতিস্থাপন করতে চাইছি। উদাহরণস্বরূপ সমস্ত ব্যবহারকারী $ r. user.name object "ব্যবহারকারীর" অবজেক্টে নামের সম্পত্তি সহ প্রতিস্থাপন করুন।
জো

@ সার্গ: হ্যাঁ এটি একটি বেগ কোড। এবং আমি আমার কোড থেকে বেগটি সরাতে চাই।
জো

উত্তর:


147

StringSubstitutorঅ্যাপাচি কমন্স পাঠ্য থেকে ব্যবহার করুন ।

https://commons.apache.org/proper/commons-text/

এটি এটি আপনার জন্য করবে (এবং এর মুক্ত উত্স ...)

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


4
হওয়া উচিত Map<String, String> valuesMap = new HashMap<String, String>();
অ্যান্ড্রুজোনস

4
StrSubstitutorএখন https://commons.apache.org/proper/commons-lang/ এ হ্রাস করা হয়েছে । পরিবর্তে ব্যবহারকারী https://commons.apache.org/proper/commons-text/
লুকুলুবা

7
StrSubstitutor১.৩ হিসাবে অবমানিত, StringSubstitutorপরিবর্তে ব্যবহার করুন। এই শ্রেণীটি 2.0 তে সরানো হবে। আমদানি করার জন্য Gradle নির্ভরতা StringSubstitutorহয়org.apache.commons:commons-text:1.4
Yurii Rabeshko

এটি শর্ত ভিত্তিক প্রতিস্থাপনের অনুমতি দেয়?
গৌরব

132

java.text.MessageFormatক্লাসটি একবার দেখুন , ম্যাসেজফর্ম্যাট অবজেক্টের একটি সেট নেয়, সেগুলিকে ফর্ম্যাট করে, তারপরে উপযুক্ত জায়গাগুলিতে বিন্যাসিত স্ট্রিংগুলি প্যাটার্নে সন্নিবেশ করায়।

Object[] params = new Object[]{"hello", "!"};
String msg = MessageFormat.format("{0} world {1}", params);

10
ধন্যবাদ! আমি জানতাম জাভাতে কোনও অভ্যন্তরীন উপায় থাকা উচিত এটি ব্যবহার না করেই এমন সহজ কাজটি করার জন্য টেম্পলেট ইঞ্জিনকে ফ্র্যাকিং করা উচিত!
জোসেফ রাজীব মোঠা

4
দেখে মনে হচ্ছে স্ট্রিং.ফর্ম্যাট এটি করতে পারে এমন কিছু করতে পারে - stackoverflow.com/questions/2809633/…
নওম্যানন

6
+1 সচেতন থাকুন formatএছাড়াও একটি Object...ভার্সেস লাগে যাতে আপনি এই আরও সংখ্যক format("{0} world {1}", "Hello", "!");
সংশ্লেষ

এটি লক্ষ করা উচিত যে MessageFormatকেবল নির্ভরযোগ্যরূপে এটির নামসই, প্রদর্শন বার্তাগুলির জন্য ব্যবহার করা যেতে পারে, যেখানে আউটপুটে প্রযুক্তিগত বিন্যাস সম্পর্কিত বিষয় নয়। উদাহরণস্বরূপ নম্বরগুলি লোকেল সেটিংসে ফর্ম্যাট হবে, প্রযুক্তিগত ব্যবহারের জন্য এগুলিকে অবৈধ উপস্থাপন করবে।
Marnes

25

আমার পছন্দের উপায় হ'ল String.format()কারণ এটি অনলাইনার এবং তৃতীয় পক্ষের গ্রন্থাগারগুলির প্রয়োজন নেই:

String message = String.format("Hello! My name is %s, I'm %s.", name, age); 

আমি এটি নিয়মিত ব্যবহার করি, যেমন ব্যতিক্রম বার্তায়:

throw new Exception(String.format("Unable to login with email: %s", email));

ইঙ্গিত: আপনি নিজের পছন্দমতো ভেরিয়েবল রাখতে পারেন কারণ ভারারাগুলিformat() ব্যবহার করে


আপনি যখন একই যুক্তিকে একাধিকবার পুনরাবৃত্তি করতে চান তখন এটি কম কার্যকর। উদাহরণ: String.format("Hello! My name is %s, I'm %s. Why is my name %s you ask? Well I'm only %s years old so I don't know", name, age, name, age);। এখানে অন্যান্য উত্তরের জন্য প্রতিটি যুক্তি কেবল একবারে নির্দিষ্ট করা দরকার।
আশেরবার

4
@ শেরবার আপনি ফর্ম্যাট স্ট্রিংয়ে যুক্তি সূচক স্পেসিফায়ার ব্যবহার করতে পারেন, যেমনString.format("Hello! My name is %1$s, I'm %2$s. Why is my name %1$s you ask? Well I'm only %2$s years old so I don't know", name, age)
জাজপি

@ জাজপপি আমি কখনই তা জানতাম না। ধন্যবাদ!
আশেরবার

20

আমি এটির একটি ছোট পরীক্ষা প্রয়োগ একত্রিত করেছিলাম। মূল ধারণাটি হ'ল formatফর্ম্যাট স্ট্রিং, এবং বস্তুর মানচিত্র এবং স্থানীয়ভাবে তাদের নামগুলি কল করা এবং পাস করা।

নিম্নলিখিত ফলাফল আউটপুট হয়:

আমার কুকুরটির নাম ফিদো, এবং জেন ডো তার মালিক।

public class StringFormatter {

    private static final String fieldStart = "\\$\\{";
    private static final String fieldEnd = "\\}";

    private static final String regex = fieldStart + "([^}]+)" + fieldEnd;
    private static final Pattern pattern = Pattern.compile(regex);

    public static String format(String format, Map<String, Object> objects) {
        Matcher m = pattern.matcher(format);
        String result = format;
        while (m.find()) {
            String[] found = m.group(1).split("\\.");
            Object o = objects.get(found[0]);
            Field f = o.getClass().getField(found[1]);
            String newVal = f.get(o).toString();
            result = result.replaceFirst(regex, newVal);
        }
        return result;
    }

    static class Dog {
        public String name;
        public String owner;
        public String gender;
    }

    public static void main(String[] args) {
        Dog d = new Dog();
        d.name = "fido";
        d.owner = "Jane Doe";
        d.gender = "him";
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("d", d);
        System.out.println(
           StringFormatter.format(
                "My dog is named ${d.name}, and ${d.owner} owns ${d.gender}.", 
                map));
    }
}

নোট: আনহ্যান্ডেল ব্যতিক্রমের কারণে এটি সংকলন করে না। তবে কোডটি পড়া সহজ করে তোলে।

এছাড়াও, আমি পছন্দ করি না যে আপনাকে কোডটিতে মানচিত্রটি নিজেই তৈরি করতে হবে, তবে স্থানীয় ভেরিয়েবলের নামটি কীভাবে অগ্রগতিতে নেওয়া যায় তা আমি জানি না। এটি করার সর্বোত্তম উপায় হ'ল এটি তৈরি করার সাথে সাথে মানচিত্রটিতে রাখা উচিত।

নীচের উদাহরণটি আপনার উদাহরণ থেকে ফলাফলগুলি তৈরি করে:

public static void main(String[] args) {
    Map<String, Object> map = new HashMap<String, Object>();
    Site site = new Site();
    map.put("site", site);
    site.name = "StackOverflow.com";
    User user = new User();
    map.put("user", user);
    user.name = "jjnguy";
    System.out.println(
         format("Hello ${user.name},\n\tWelcome to ${site.name}. ", map));
}

আমার আরও উল্লেখ করা উচিত যে বেগটি কী তা আমার কোনও ধারণা নেই, তাই আমি আশা করি এই উত্তরটি প্রাসঙ্গিক।


এই আমি খুঁজছিলাম ছিল। একটি বাস্তবায়ন দেওয়ার জন্য আপনাকে ধন্যবাদ। আমি এটির জন্য চেষ্টা করেছিলাম এবং ভুল ফলাফল পাচ্ছিলাম। : ডি। যাইহোক এটি আমার সমস্যার সমাধান করেছে।
জো

4
@ জো, খুশী আমি সাহায্য করতে পারলাম। পরিশেষে জাভাতে প্রতিবিম্ব ব্যবহার করে এমন কিছু কোড লেখার অনুশীলন করা আমার পক্ষে একটি ভাল অজুহাত ছিল।
jjnguy

6

আপনি কীভাবে এটি করতে যেতে পারেন তার একটি রূপরেখা এখানে দেওয়া হয়েছে। এটিকে আসল কোড হিসাবে প্রয়োগ করার জন্য তুলনামূলকভাবে সহজ হওয়া উচিত।

  1. টেমপ্লেটে রেফারেন্স করা হবে এমন সমস্ত বস্তুর একটি মানচিত্র তৈরি করুন।
  2. টেমপ্লেটে পরিবর্তনশীল উল্লেখগুলি খুঁজে পেতে এবং তাদের মানগুলির সাথে প্রতিস্থাপনের জন্য একটি নিয়মিত অভিব্যক্তি ব্যবহার করুন (পদক্ষেপ 3 দেখুন)। ম্যাচার বর্গ উপকারে আসা খুঁজে-এবং-প্রতিস্থাপন জন্য হবে।
  3. পরিবর্তনশীল নামটি বিন্দুতে বিভক্ত করুন। user.nameহয়ে যাবে userএবং name। দেখুন userআপনার মানচিত্রে বস্তুর এবং ব্যবহার পেতে প্রতিফলন মান প্রাপ্ত করার nameবস্তু থেকে। ধরে নেওয়া আপনার আইটেমের স্ট্যান্ডার্ড গেটার রয়েছে, আপনি কোনও পদ্ধতি সন্ধান করবেন getNameএবং এটি শুরু করবেন।

হেই, কেবল এই উত্তরটি দেখেছি। এটা আমার মত। আপনি আমার প্রয়োগ সম্পর্কে কী ভাবছেন দয়া করে আমাকে জানান me
jjnguy

5

এক্সপ্রেশন ল্যাঙ্গুয়েজ বাস্তবায়ন দু'টি আছে যা আপনার জন্য এটি করে, আপনার নিজের প্রয়োগ হিসাবে বা আপনার প্রয়োজনীয়তা বৃদ্ধি পেতে পছন্দনীয় হতে পারে, উদাহরণস্বরূপ JUEL এবং MVEL দেখুন

আমি পছন্দ করেছি এবং কমপক্ষে একটি প্রকল্পে সাফল্যের সাথে এমভিইএল ব্যবহার করেছি।

নন জেএসপি (স্ট্যান্ডলোন) প্রসঙ্গে স্ট্যাকফ্লো পোস্ট জেএসটিএল / জেএসপি ইএল (এক্সপ্রেশন ভাষা) দেখুন


0

বাক্সের বাইরে গতির সাথে তুলনীয় এমন কিছুই নেই যেহেতু বেগটি ঠিক সেই সমস্যাটি সমাধান করার জন্য লেখা হয়েছিল। আপনি যে নিকটতম জিনিসটি চেষ্টা করতে পারেন সেটি হ'ল ফর্ম্যাটটারটি অনুসন্ধান করা

http://cupi2.uniandes.edu.co/site/images/recursos/javadoc/j2se/1.5.0/docs/api/java/util/ Formatter.html

তবে যতদূর আমি জানি যে ফর্ম্যাটারটি জাভাতে ফরম্যাটিং বিকল্পগুলির মতো সি প্রদানের জন্য তৈরি করা হয়েছিল যাতে এটি আপনার চুলকায় ঠিক না স্ক্র্যাচ করতে পারে তবে আপনি চেষ্টা করার জন্য স্বাগত।


0

আমি গ্রোভি জিস্ট্রিংয়ের সাথে টেমপ্লেটটি পার্স করতে জাভাতে গ্রোভিশেল ব্যবহার করি:

Binding binding = new Binding();
GroovyShell gs = new GroovyShell(binding);
// this JSONObject can also be replaced by any Java Object
JSONObject obj = new JSONObject();
obj.put("key", "value");
binding.setProperty("obj", obj)
String str = "${obj.key}";
String exp = String.format("\"%s\".toString()", str);
String res = (String) gs.evaluate(exp);
// value
System.out.println(str);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.