ฉันต้องการตัดสตริงหากความยาวเกิน 10 อักขระ
สมมติว่าหากความยาวสาย 12 ( String s="abcdafghijkl"
) "abcdefgh.."
แล้วสตริงตัดแต่งใหม่จะประกอบด้วย
ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
ฉันต้องการตัดสตริงหากความยาวเกิน 10 อักขระ
สมมติว่าหากความยาวสาย 12 ( String s="abcdafghijkl"
) "abcdefgh.."
แล้วสตริงตัดแต่งใหม่จะประกอบด้วย
ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
คำตอบ:
s = s.substring(0, Math.min(s.length(), 10));
ใช้เช่นนี้หลีกเลี่ยงข้อยกเว้นในกรณีที่สตริงที่มีอยู่แล้วที่สั้นกว่าMath.min
10
หมายเหตุ:
ข้างต้นทำการตัดแต่งจริง ถ้าคุณต้องการจริงที่จะมาแทนที่ช่วงสาม (!) ตัวอักษรที่มีจุดถ้ามันตัดทอนแล้วใช้ Apache StringUtils.abbreviate
คอมมอนส์
สิ่งนี้อาจทำงานไม่ถูกต้อง1หากสตริงของคุณมีจุดรหัส Unicode นอก BMP เช่น Emojis สำหรับ (ซับซ้อนมากขึ้น) การแก้ปัญหาที่ทำงานอย่างถูกต้องสำหรับทุก Unicode รหัสจุดดู @ sibnick ของการแก้ปัญหา
1 - จุดรหัส Unicode ที่ไม่ได้อยู่บนระนาบ 0 (BMP) จะแสดงเป็น "คู่ตัวแทน" (คือสองchar
ค่า) ในString
. การเพิกเฉยต่อสิ่งนี้เราอาจตัดทอนโค้ดให้น้อยกว่า 10 จุดหรือ (แย่กว่านั้น) ตัดตรงกลางคู่ตัวแทน ในทางกลับกันString.length()
ไม่ได้เป็นการวัดความยาวข้อความ Unicode ในอุดมคติอีกต่อไปดังนั้นการตัดแต่งโดยอ้างอิงจากข้อมูลดังกล่าวอาจเป็นสิ่งที่ไม่ถูกต้อง
s = (s.length() > 10) ? s.substring(0,10) : s ;
StringUtils.abbreviate
จากห้องสมุดApache Commons Langอาจเป็นเพื่อนของคุณ:
StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
Commons Lang3อนุญาตให้ตั้งค่าสตริงที่กำหนดเองเป็นเครื่องหมายแทนที่ ด้วยวิธีนี้คุณสามารถตั้งค่าจุดไข่ปลาอักขระเดี่ยวได้
StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"
มีStringUtils
ฟังก์ชันApache Commons ที่ทำสิ่งนี้
s = StringUtils.left(s, 10)
หากไม่มีอักขระ len หรือสตริงเป็นโมฆะสตริงจะถูกส่งกลับโดยไม่มีข้อยกเว้น สตริงว่างจะถูกส่งกลับหาก len เป็นค่าลบ
StringUtils.left (null, ) = null
StringUtils.left ( , -ve) = ""
StringUtils.left ("", *) = ""
StringUtils.left ("abc", 0) = ""
StringUtils.left (" abc ", 2) =" ab "
StringUtils.left (" abc ", 4) =" abc "
มารยาท: Steeve McCauley
ตามปกติไม่มีใครสนใจคู่ตัวแทน UTF-16 ดูเกี่ยวกับพวกเขา: อักขระ Unicode ที่ไม่ใช่ BMP ที่พบบ่อยที่สุดในการใช้งานจริงคืออะไร? แม้แต่ผู้เขียน org.apache.commons / commons-lang3
คุณสามารถเห็นความแตกต่างระหว่างรหัสที่ถูกต้องและรหัสปกติในตัวอย่างนี้:
public static void main(String[] args) {
//string with FACE WITH TEARS OF JOY symbol
String s = "abcdafghi\uD83D\uDE02cdefg";
int maxWidth = 10;
System.out.println(s);
//do not care about UTF-16 surrogate pairs
System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
//correctly process UTF-16 surrogate pairs
if(s.length()>maxWidth){
int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
}
}
s = s.length() > 10 ? s.substring(0, 9) : s;
หรือคุณสามารถใช้วิธีนี้ในกรณีที่คุณไม่มี StringUtils ในมือ:
public static String abbreviateString(String input, int maxLength) {
if (input.length() <= maxLength)
return input;
else
return input.substring(0, maxLength-2) + "..";
}
System.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
ในกรณีที่คุณกำลังมองหาวิธีตัดและคงอักขระ 10 ตัวสุดท้ายของสตริงไว้
s = s.substring(Math.max(s.length(),10) - 10);
ด้วย Kotlin มันง่ายเหมือน:
yourString.take(10)
ส่งคืนสตริงที่มีอักขระ n ตัวแรกจากสตริงนี้หรือทั้งสตริงหากสตริงนี้สั้นกว่า
ดูเหมือนว่าคุณจะขอตัวละครจุดไข่ปลา ( …
) ในตำแหน่งสุดท้ายเมื่อตัดทอน นี่คือหนึ่งซับในการจัดการสตริงอินพุตของคุณ
String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
ดูโค้ดนี้ใช้งานได้ที่ IdeOne.com
ABCDEFGHI ...
เราสามารถทำให้หนึ่งซับโดยใช้ประกอบ ternary
String input = "abcdefghijkl" ;
String output =
( input.length() > 10 ) // If too long…
?
input
.substring( 0 , 10 - 1 ) // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
.concat( "…" ) // Add the ellipsis character.
: // Or, if not too long…
input // Just return original string.
;
ดูโค้ดนี้ใช้งานได้ที่ IdeOne.com
ABCDEFGHI ...
สิ่งอำนวยความสะดวก Java Streams ทำให้สิ่งนี้น่าสนใจตั้งแต่ Java 9 และใหม่กว่า น่าสนใจ แต่อาจไม่ใช่แนวทางที่ดีที่สุด
เราใช้จุดรหัสมากกว่าchar
ค่า char
ประเภทคือมรดกและจะถูก จำกัดย่อยของเป็นไปได้ทั้งหมดUnicodeตัวอักษร
String input = "abcdefghijkl" ;
int limit = 10 ;
String output =
input
.codePoints()
.limit( limit )
.collect( // Collect the results of processing each code point.
StringBuilder::new, // Supplier<R> supplier
StringBuilder::appendCodePoint, // ObjIntConsumer<R> accumulator
StringBuilder::append // BiConsumer<R,R> combiner
)
.toString()
;
ถ้าเรามีตัวละครส่วนเกินตัดทอนแทนที่ตัวอักษรตัวสุดท้ายที่มี จุดไข่ปลา
if ( input.length () > limit )
{
output = output.substring ( 0 , output.length () - 1 ) + "…";
}
ถ้าฉันคิดวิธีรวมสายสตรีมด้วยส่วน "ถ้าเกินขีด จำกัด ให้ทำจุดไข่ปลา"
str==null ? str : str.substring(0, Math.min(str.length(), 10))
หรือ,
str==null ? "" : str.substring(0, Math.min(str.length(), 10))
ทำงานร่วมกับ null