การแยกสตริง Java ลบค่าว่าง


286

ฉันกำลังพยายามแบ่งค่าโดยใช้ตัวคั่น แต่ฉันกำลังค้นหาผลลัพธ์ที่น่าประหลาดใจ

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

ฉันคาดหวังว่าจะได้รับ 8 ค่า [5,6,7, ว่างเปล่า, 8,9, ว่างเปล่า, ว่างเปล่า] แต่ฉันได้รับเพียง 6 ค่า

ความคิดและวิธีการแก้ไขใด ๆ ไม่ว่าค่าว่างจะมาที่ใดก็ควรอยู่ในอาร์เรย์

คำตอบ:


493

split(delimiter)โดยค่าเริ่มต้นจะลบสตริงว่างต่อท้ายออกจากอาร์เรย์ผลลัพธ์ ในการปิดกลไกนี้เราจำเป็นต้องใช้รุ่นที่มีการโอเวอร์โหลดของsplit(delimiter, limit)พร้อมกับlimitตั้งค่าเป็นค่าลบเช่น

String[] split = data.split("\\|", -1);

รายละเอียดเพิ่มเติมเล็กน้อย:
split(regex)ส่งคืนผลลัพธ์ภายในsplit(regex, 0)และในเอกสารของวิธีนี้คุณสามารถค้นหาได้ (เน้นที่เหมือง)

limitพารามิเตอร์ควบคุมจำนวนครั้งรูปแบบถูกนำไปใช้และดังนั้นจึงส่งผลกระทบต่อความยาวของอาร์เรย์ที่เกิด

หากวงเงินที่nเป็นมากกว่าศูนย์แล้วรูปแบบจะถูกนำมาใช้มากที่สุด n - 1 ครั้ง, ความยาวของอาเรย์จะมากขึ้นกว่าไม่มี n และรายการสุดท้ายของอาเรย์จะมีการป้อนข้อมูลทั้งหมดเกินคั่นจับคู่สุดท้าย

หากไม่nเป็นบวกรูปแบบจะถูกนำไปใช้หลายครั้งมากที่สุดและอาร์เรย์สามารถมีความยาวได้

หากnมีที่ศูนย์แล้วรูปแบบจะถูกนำมาใช้หลายครั้งตามที่เป็นไปได้อาร์เรย์สามารถมีความยาวใด ๆ และต่อท้ายสตริงที่ว่างเปล่าจะถูกยกเลิก

ข้อยกเว้น :

เป็นมูลค่าการกล่าวขวัญว่าการลบต่อท้ายสตริงว่างทำให้รู้สึกเฉพาะในกรณีที่สายที่ว่างเปล่าเช่นพัสดุที่สร้างขึ้นโดยกลไกการแยก ดังนั้น"".split(anything)เนื่องจากเราไม่สามารถแยกได้""ไกลขึ้นเราจะได้ผลลัพธ์ตาม[""]ลำดับ
มันเกิดขึ้นเพราะการแยกไม่ได้เกิดขึ้นที่นี่ดังนั้น""แม้จะว่างเปล่าและการติดตามแทนสตริงเดิมไม่ใช่สตริงว่างซึ่งสร้างขึ้นโดยกระบวนการแยก


2
ว้าว. ที่ทำงานเก่ง แต่ -1 สิ่งนี้เปลี่ยนแปลงทุกสิ่งได้อย่างไร
Reddy

1
คุณสามารถลองด้วยdata.split("\\|", 8)
Subhrajyoti Majumder

23
อย่าใช้split("\\|", 8)เพราะข้อ จำกัด นี้สำหรับโทเค็นแปดตัวแรก! หากสตริงของคุณเป็นตัวแปรคุณควรใช้split("\\|", -1)เพื่อให้มันสร้างโทเค็นได้ไม่ จำกัด จำนวนและไม่ต้องทิ้งโทเค็นที่ว่างเปล่าในตอนท้าย
ADTC

2
@Reddy -1 ( หรือจำนวนลบใด ๆ ในความเป็นจริงมันไม่สำคัญว่าค่าสัมบูรณ์คืออะไร ) บอกวิธีการแบ่งเพื่อให้โทเค็นที่ว่างเปล่าในตอนท้าย ค่าเริ่มต้นคือ 0 ซึ่งบอกวิธีการละทิ้งโทเค็นที่ว่างเปล่าในตอนท้ายของอาร์เรย์
ADTC

8
split(regex)เห็นได้ชัดว่าผู้คนจำนวนมากคาดว่าการรักษาต่อท้ายสตริงที่ว่างเปล่าเป็นฟังก์ชั่นเริ่มต้นสำหรับ พวกเขาลงเอยที่นี่และพบว่าไม่ใช่
Attila Tanyi

32

จากเอกสารของString.split(String regex):

วิธีการนี้ทำงานราวกับว่าโดยการเรียกใช้วิธีการแยกสองข้อโต้แย้งที่มีการแสดงออกที่กำหนดและข้อโต้แย้งที่เป็นศูนย์ สตริงว่างเปล่าต่อท้ายจึงไม่รวมอยู่ในอาร์เรย์ผลลัพธ์

ดังนั้นคุณจะต้องใช้อาร์กิวเมนต์ทั้งสองรุ่นString.split(String regex, int limit)ด้วยค่าลบ:

String[] split = data.split("\\|",-1);

หมอ:

หากขีด จำกัด n มากกว่าศูนย์รูปแบบจะถูกนำมาใช้มากที่สุด n - 1 ครั้งความยาวของอาร์เรย์จะไม่มากกว่า n และรายการสุดท้ายของอาร์เรย์จะมีอินพุตทั้งหมดนอกเหนือจากตัวคั่นที่ตรงกันล่าสุด หาก n ไม่เป็นบวกรูปแบบจะถูกนำไปใช้หลายครั้งมากที่สุดและอาร์เรย์สามารถมีความยาวได้ หาก n เป็นศูนย์ดังนั้นรูปแบบจะถูกนำไปใช้หลายครั้งมากที่สุดอาร์เรย์สามารถมีความยาวใด ๆ และสตริงว่างที่ต่อท้ายจะถูกทิ้ง

สิ่งนี้จะไม่ทำให้องค์ประกอบที่ว่างเปล่าว่างเปล่ารวมถึงสิ่งที่ตามมา


4

จากString.split () API Doc :

แยกสตริงนี้รอบการแข่งขันของนิพจน์ปกติที่กำหนด วิธีการนี้จะทำงานราวกับว่าโดยการเรียกใช้วิธีการแยกสองข้อโต้แย้งที่มีการแสดงออกที่กำหนดและข้อโต้แย้งที่เป็นศูนย์ สตริงว่างเปล่าต่อท้ายจึงไม่รวมอยู่ในอาร์เรย์ผลลัพธ์

Overloaded String.split (regex, int)เหมาะสมกว่าสำหรับกรณีของคุณ


1
นั่นอธิบายพฤติกรรม แต่ไม่ตอบคำถาม
assylias

@assylias เพิ่มไปยังคำตอบของฉันตอนนี้ :)
PermGenError

4

String[] split = data.split("\\|",-1);

นี่ไม่ใช่ความต้องการที่แท้จริงในทุกเวลา ข้อเสียของด้านบนแสดงอยู่ด้านล่าง:

Scenerio 1:
When all data are present:
    String data = "5|6|7||8|9|10|";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 7
    System.out.println(splt.length); //output: 8

เมื่อข้อมูลหายไป:

Scenerio 2: Data Missing
    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output: 8

ข้อกำหนดที่แท้จริงคือความยาวควรเป็น 7 แม้ว่าข้อมูลจะหายไป เพราะมีหลายกรณีเช่นเมื่อฉันต้องใส่ในฐานข้อมูลหรืออย่างอื่น เราสามารถทำได้โดยใช้วิธีการด้านล่าง

    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output:7

สิ่งที่ฉันทำที่นี่คือฉันกำลังลบ "|" ท่อที่ท้ายแล้วแยกสตริง หากคุณมี "," เป็นตัวคั่นคุณต้องเพิ่ม ", $" ใน replaceAll


1

คุณอาจมีตัวคั่นหลายตัวรวมถึงอักขระช่องว่างเครื่องหมายจุลภาคเครื่องหมายอัฒภาค ฯลฯ ใช้เวลาในกลุ่มที่ทำซ้ำได้ด้วย [] + เช่น:

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

คุณจะมี 4 โทเค็น - a, b, c, d

ตัวคั่นนำหน้าในสตริงซอร์สต้องถูกลบออกก่อนใช้การแยกนี้

ตามคำตอบของคำถามที่ถาม:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

ช่องว่างเพิ่มในกรณีที่ถ้าคุณมีตัวคั่นเป็นพร้อมกับ |

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