จะใช้วิธีการ `string.startsWith ()` ละเว้นเคสได้อย่างไร


115

ฉันต้องการใช้string.startsWith()วิธีการ แต่ไม่สนใจกรณี

สมมติว่าฉันมีString"เซสชัน" และฉันจะใช้startsWithที่ "sEsSi" trueแล้วมันควรจะกลับมา

ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?


5
ไม่มีเหตุผลที่จะปิดคำถามนี้ อย่างไรก็ตามทางออกที่ดีที่สุดคือการใช้string.regionMatches(true, 0, prefix, 0, prefix.length());ที่ไม่ต้องเสียค่าใช้จ่ายในการ "normalizing" ทั้งสองสตริง
isapir

@AlexanderAbakumov Fine โดยฉัน คำตอบที่ถูกต้องโพสต์ไว้ในความคิดเห็นของฉันด้านบน มีประสิทธิภาพมากกว่าการเปลี่ยนกรณีของสตริง จะเป็นการดีที่จะอัปเกรดเป็นคำตอบแทนที่จะเป็นความคิดเห็น
isapir

คำตอบ:


98

ใช้toUpperCase()หรือtoLowerCase()เพื่อสร้างมาตรฐานสตริงของคุณก่อนทดสอบ


8
ปัญหาใหญ่ที่นี่คือประสิทธิภาพ สำหรับสตริงขนาดเล็กไม่มีปัญหา แต่ถ้าคุณมีตัวใหญ่ ... ฉันหมายถึง ... คุณจะทำ toUpperCase ในสตริงขนาด 1mb จริง ๆ เพื่อเปรียบเทียบอักขระแบบไม่เป็นทางการ 4-10 ตัวหรือไม่?
Dyorgio

4
แม้ว่าฉันจะไม่เห็นว่าทำไมฉันถึงต้องการเปรียบเทียบส่วนเริ่มต้นของสตริง 1mb ถ้ามีเพียง 4-10 ตัวอักษรเริ่มต้นที่ฉันสนใจฉันใช้สตริงย่อยแล้วทำให้เป็นปกติและทำ ...
ซวย

3
คำตอบนี้ (และคำตอบอื่น ๆ ทั้งหมดที่พบในที่นี้) ผิด หากคุณดูการใช้งานString.equalsIgnoreCase()คุณจะพบว่าคุณจำเป็นต้องเปรียบเทียบStrings ทั้งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ก่อนจึงจะสรุปfalseได้ โปรดดูstackoverflow.com/a/38947571/14731สำหรับคำตอบอื่น
Gili

10
คำตอบนี้ไม่เป็นความจริงเนื่องจาก toLowerCase () ใช้ Locale.getDefault () เป็นการภายในเพื่อเปลี่ยนอักขระและอาจนำไปสู่เชิงลบที่ผิดพลาด สมมติว่าคุณต้องการเปรียบเทียบ "อิสตันบูล" กับ "อิสตันบูล" ในการเทียบเท่าตัวพิมพ์เล็ก "İ" ของภาษาตุรกีคือ "ı" ดังนั้นเมื่อฉันพยายามทำสิ่งนั้น"İstanbul".toLowerCase().startsWith("istanbul".toLowerCase())(ในพื้นที่ของตุรกี) มันจะทำให้ฉันเป็นเท็จ
Mustafa Berkay Mutlu

1
@ เนเมซิสคำตอบนี้ไม่ถูกต้องหากเป็นคำตอบที่ได้รับการยอมรับอาจทำให้หลายคนเข้าใจผิด คุณช่วยแก้ไขคำตอบของคุณและเชื่อมโยงไปยังคำตอบของ Rohit Jain ได้ไหม
โมฮาอูฐผู้ทรงอำนาจ

88

ทางเลือกหนึ่งคือการแปลงทั้งสองเป็นตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่:

"Session".toLowerCase().startsWith("sEsSi".toLowerCase());

นี่เป็นสิ่งที่ไม่ถูกต้อง ดู: https://stackoverflow.com/a/15518878/14731


อีกทางเลือกหนึ่งคือการใช้String#regionMatches()method ซึ่งใช้อาร์กิวเมนต์บูลีนที่ระบุว่าจะทำการจับคู่แบบคำนึงถึงขนาดตัวพิมพ์หรือไม่ คุณสามารถใช้งานได้ดังนี้:

String haystack = "Session";
String needle = "sEsSi";
System.out.println(haystack.regionMatches(true, 0, needle, 0, 5));  // true

ตรวจสอบว่าพื้นที่needleจากดัชนี0จนถึงความยาว5มีอยู่ในการhaystackเริ่มต้นจากดัชนี0จนถึงความยาว5หรือไม่ อาร์กิวเมนต์แรกคือtrueหมายความว่าจะทำการจับคู่แบบไม่คำนึงถึงขนาดตัวพิมพ์


และถ้าคุณเป็นแฟนตัวยงของRegexคุณสามารถทำสิ่งนี้ได้:

System.out.println(haystack.matches("(?i)" + Pattern.quote(needle) + ".*"));

(?i) แฟล็กที่ฝังไว้สำหรับละเว้นการจับคู่กรณี


1
จริงๆแล้วสมมติว่ามีตารางที่มีมากกว่า 1 แสนรายการและฉันใช้ for loop ในคอลัมน์ใดคอลัมน์หนึ่งเพื่อแยกวิเคราะห์รายการเหล่านั้นทั้งหมดและในนั้นฉันพยายามใช้ตัวพิมพ์เล็กด้านบนนี้เพื่อค้นหารายการที่เริ่มต้นด้วยรูปแบบเฉพาะ . ดังนั้นนี่จึงทำให้เกิดปัญหาด้านประสิทธิภาพ หากไม่พบรายการที่ตรงกันเลยระบบจะแยกวิเคราะห์รายการทั้งหมดภายในซึ่งจะใช้เวลานานพอสมควรในขณะเดียวกันก็จะถูกแปลงเป็นตัวพิมพ์เล็กเช่นกัน มีตัวเลือกอื่นในการแก้ไขปัญหาด้านประสิทธิภาพหรือไม่?
Sheetal Bhatewara

@Rohit Jain นี่ System.out.println("Session".toLowerCase().startsWith("sEsSi".toLowerCase()));ไม่ใช่วิธีแก้ปัญหา คุณสามารถลองสิ่งนี้: System.out.println("SessIon".toLowerCase().startsWith("sEsSi".toLowerCase()));ด้วยอาร์กิวเมนต์ vm -Duser.country=TR -Duser.language=tr ในตัวอย่างนี้Iเป็นตัวพิมพ์ใหญ่i
DPM



2

ฉันรู้ว่าฉันมาสาย แต่ถ้าใช้ StringUtils.startsWithIgnoreCase () จาก Apache Commons Lang 3 ล่ะ

ตัวอย่าง:

StringUtils.startsWithIgnoreCase(string, "start");

เพียงเพิ่มการอ้างอิงต่อไปนี้ในไฟล์ pom.xml ของคุณ (โดยใช้สมมติฐานที่คุณใช้ Maven):

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.