วิธีจัดรูปแบบสตริงใน Java


185

คำถามดั้งเดิม แต่ฉันจะจัดรูปแบบสตริงเช่นนี้ได้อย่างไร:

"ขั้นตอน {1} จาก {2}"

โดยการแทนที่ตัวแปรโดยใช้ Java? ใน C # มันง่าย



คำตอบ:


140

นอกจากนี้ในการ String.format java.text.MessageFormatยังใช้เวลาดู รูปแบบย่อน้อยลงและใกล้ชิดกับตัวอย่าง C # ที่คุณให้มากขึ้นและคุณสามารถใช้ในการแยกวิเคราะห์ได้เช่นกัน

ตัวอย่างเช่น:

int someNumber = 42;
String someString = "foobar";
Object[] args = {new Long(someNumber), someString};
MessageFormat fmt = new MessageFormat("String is \"{1}\", number is {0}.");
System.out.println(fmt.format(args));

ตัวอย่างที่ดีกว่าใช้ประโยชน์จาก varargs และการปรับปรุง autoboxing ใน Java 1.5 และเปลี่ยนสิ่งข้างต้นเป็นแบบซับใน:

MessageFormat.format("String is \"{1}\", number is {0}.", 42, "foobar");

MessageFormatดีขึ้นเล็กน้อยสำหรับการทำพหูพจน์ i18nized ด้วยตัวเลือกปรับปรุง ในการระบุข้อความที่ใช้รูปแบบเอกฐานอย่างถูกต้องเมื่อตัวแปรคือ 1 และพหูพจน์อื่นคุณสามารถทำสิ่งนี้:

String formatString = "there were {0} {0,choice,0#objects|1#object|1<objects}";
MessageFormat fmt = new MessageFormat(formatString);
fmt.format(new Object[] { new Long(numberOfObjects) });

21
MessageFormat มีวัตถุประสงค์เพื่อการแปลดังนั้นควรใช้ความระมัดระวัง ตัวอย่างเช่นรหัสต่อไปนี้MessageFormat.format("Number {0}", 1234));ขึ้นอยู่กับสถานที่เริ่มต้นสามารถผลิตแทนNumber 1,234 Number 1234
pavel_kazlou

@ataylor: สวัสดีขอโทษด้วย แต่ฉันสับสนเล็กน้อย ฉันต้องการบางอย่างเช่นที่ฉันจะส่งผ่านวัตถุคลาสที่มีข้อมูล & เมื่อ{0} it ll take firstnameเวลาเมื่อ{1} then lastnameเช่นนั้น เป็นไปได้เช่น{0,choice,0.getFirstName()}หรืออะไรแบบนั้น?
user3145373 ツ

@ user3145373 ツฉันไม่คิดอย่างนั้น
ataylor

ตกลงดีฉันได้อ้างอิงหนึ่งโครงการ. Net เช่นเดียวกับที่ฉันต้องการcodeproject.com/Articles/42310/ …อ้างอิงโครงการนี้ฉันกำลังมองหาสิ่งนี้ หากคุณรู้ว่ามีโครงการหรือแพ็คเกจใด ๆ เช่นนั้นโปรดบอกฉัน ขอบคุณ
user3145373 ツ

233

ลองดูที่String.format อย่างไรก็ตามโปรดทราบว่าจะใช้ตัวระบุรูปแบบคล้ายกับฟังก์ชันของตระกูล printf ของ C - ตัวอย่างเช่น:

String.format("Hello %s, %d", "world", 42);

จะกลับมา "Hello world, 42" คุณอาจพบนี้เป็นประโยชน์เมื่อเรียนรู้เกี่ยวกับ specifiers รูปแบบ แอนดี้โธมัส - แครมเมอร์ก็ใจดีพอที่จะทิ้งลิงค์นี้ไว้ในคอมเม้นต์ด้านล่างซึ่งดูเหมือนจะชี้ไปที่สเป็คอย่างเป็นทางการ คนที่ใช้บ่อยที่สุดคือ:

  • % s - แทรกสตริง
  • % d - ใส่จำนวนเต็มที่ลงนาม (ทศนิยม)
  • % f - ใส่จำนวนจริงสัญลักษณ์มาตรฐาน

สิ่งนี้แตกต่างอย่างสิ้นเชิงจาก C # ซึ่งใช้การอ้างอิงตำแหน่งกับตัวระบุรูปแบบเพิ่มเติม หมายความว่าคุณไม่สามารถทำสิ่งต่าง ๆ เช่น:

String.format("The {0} is repeated again: {0}", "word");

... โดยไม่ต้องทำซ้ำพารามิเตอร์ที่ส่งผ่านไปยัง printf / format (ดูความคิดเห็นของ The Scrum Meister ด้านล่าง)


หากคุณเพียงต้องการพิมพ์ผลลัพธ์โดยตรงคุณอาจพบว่า System.out.printf ( PrintStream.printf ) ตามที่คุณต้องการ


2
ตัวเลือกอื่นคือ java.text.MessageFormat ซึ่งยอมรับสัญลักษณ์รูปแบบลักษณะ {1} สัญลักษณ์รูปแบบของ String.format () สามารถคล้ายกับสัญลักษณ์รูปแบบของ printf () ของ C - แต่สามารถแตกต่างกันได้ ดูdownload.oracle.com/javase/6/docs/api/java/util/…สำหรับไวยากรณ์ทั้งหมด
Andy Thomas

53
String.formatยังสามารถดำรงตำแหน่งเป็นตัวเลข: String.format("%2$s %1$s", "foo", "bar");จะส่งออกbar foo
The Scrum Meister

7

หากคุณเลือกที่จะไม่ใช้ String.format ตัวเลือกอื่น ๆ คือ + ตัวดำเนินการไบนารี

String str = "Step " + a + " of " + b;

นี่คือเทียบเท่า

new StringBuilder("Step ").append(String.valueOf(1)).append(" of ").append(String.valueOf(2));

แล้วแต่ว่าคุณจะเลือกใช้แบบไหน StringBuilder เร็วขึ้น แต่ความแตกต่างของความเร็วนั้นเล็กน้อย ฉันชอบที่จะใช้+โอเปอเรเตอร์ (ซึ่งทำ a StringBuilder.append(String.valueOf(X)))และอ่านง่ายกว่า)


5
หากคุณกำลังจะปฏิเสธฉันโปรดอธิบายว่าทำไม
Ryan Amos

11
1) เพื่อตอบคำถามเกี่ยวกับการจัดรูปแบบสตริงคุณจะอธิบายวิธี+การทำงานของโอเปอเรเตอร์ 2) คำอธิบายของคุณไม่ถูกต้อง +เทียบเท่ากับการใช้ไม่ได้StringBuilder (มีข้อมูลมากเกินไปสำหรับสิ่งนี้)String.concat
SørenLøvborg

6

ฉันได้เขียนวิธีการง่าย ๆ ของฉันมัน:

public class SomeCommons {
    /** Message Format like 'Some String {0} / {1}' with arguments */
    public static String msgFormat(String s, Object... args) {
        return new MessageFormat(s).format(args);
    }
}

เพื่อให้คุณสามารถใช้เป็น:

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");

5
public class StringFormat {

    public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            System.out.println("================================");
            for(int i=0;i<3;i++){
                String s1=sc.next();
                int x=sc.nextInt();
                System.out.println(String.format("%-15s%03d",s1,x));
            }
            System.out.println("================================");

    }
}

ขาออก "================================"
ved15space123 ved15space123 ved15space123 "=========== =====================

โซลูชัน Java

  • ใช้ "-" เพื่อเยื้องด้านซ้าย

  • "15" ทำให้ความยาวต่ำสุดของสตริงใช้เวลานานถึง 15

  • "s" (ซึ่งเป็นอักขระไม่กี่ตัวหลังจาก%) จะถูกแทนที่ด้วยสตริงของเรา
  • 0 คูณจำนวนเต็มกับ 0s ทางซ้าย
  • 3 ทำให้จำนวนเต็มของเรามีความยาวต่ำสุด 3


1

วิธีนี้ใช้ได้ผลสำหรับฉัน ฉันต้องการสร้าง URL สำหรับไคลเอนต์ REST แบบไดนามิกดังนั้นฉันจึงสร้างวิธีนี้ดังนั้นคุณต้องผ่าน restURL แบบนี้

/customer/{0}/user/{1}/order

และเพิ่มพารามิเตอร์ให้มากที่สุดเท่าที่คุณต้องการ:

public String createURL (String restURL, Object ... params) {       
    return new MessageFormat(restURL).format(params);
}

คุณต้องเรียกวิธีนี้ดังนี้:

createURL("/customer/{0}/user/{1}/order", 123, 321);

ผลลัพธ์

"/ ลูกค้า / 123 / ผู้ใช้ / 321 / สั่งซื้อ"


0

ฉันเขียนฟังก์ชันนี้มันทำสิ่งที่ถูกต้อง สอดแทรกคำที่ขึ้นต้นด้วย$ค่าของตัวแปรที่มีชื่อเดียวกัน

private static String interpol1(String x){
    Field[] ffield =  Main.class.getDeclaredFields();
    String[] test = x.split(" ") ;
    for (String v : test ) {
        for ( Field n: ffield ) {
            if(v.startsWith("$") && ( n.getName().equals(v.substring(1))  )){
                try {
                    x = x.replace("$" + v.substring(1), String.valueOf( n.get(null)));
                }catch (Exception e){
                    System.out.println("");
                }
            }
        }
    }
    return x;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.