ฉันจะตรวจสอบได้อย่างไรว่า Java String ไม่ใช่ช่องว่างทั้งหมด


135

ฉันต้องการตรวจสอบว่า Java String หรืออาร์เรย์อักขระไม่ได้สร้างขึ้นจากช่องว่างโดยใช้ Java?

นี่เป็นคำถามที่คล้ายกันมากยกเว้น Javascript:
ฉันจะตรวจสอบได้อย่างไรว่าสตริงมีอักขระและช่องว่างไม่ใช่เฉพาะช่องว่าง

แก้ไข : ฉันลบบิตเกี่ยวกับอักขระที่เป็นตัวเลขและตัวอักษรออกไปดังนั้นมันจึงสมเหตุสมผลกว่า


3
โปรดทราบว่าช่องว่างมีคำจำกัดความที่แตกต่างกันมากมาย: spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ คุณต้องการแบบไหน หรือจากนั้นคุณจะพูดว่า "มีอักขระที่เป็นตัวเลขและตัวอักษร" ซึ่งเป็นสิ่งที่แตกต่างกันอย่างสิ้นเชิง กรุณาชี้แจง.
Kevin Bourrillion

ขออภัยในความสับสน ... ไม่ใช่ว่าช่องว่างทั้งหมดจะเป็นกุญแจสำคัญ - โดยพื้นฐานแล้วหากมีช่องว่างทั้งหมดฉันต้องการยกเว้นเนื่องจากไม่มีเนื้อหา
Ankur

2
ด้วย JDK / 11 คุณสามารถใช้String.isBlank API เดียวกันได้
Naman

คำตอบ:


226

วิธีแก้ปัญหาที่สั้นที่สุดที่ฉันคิดได้:

if (string.trim().length() > 0) ...

สิ่งนี้จะตรวจสอบเฉพาะช่องว่าง (ไม่ใช่) สีขาว หากคุณต้องการตรวจสอบคลาสอักขระเฉพาะคุณต้องใช้อันยิ่งใหญ่match()กับ regexp เช่น:

if (string.matches(".*\\w.*")) ...

... ซึ่งตรวจสอบอักขระที่เป็นตัวเลขและตัวอักษร (ASCII) อย่างน้อยหนึ่งตัว


9
FWIW: ฉันคาดว่าโซลูชันแรกจะเร็วกว่ามาก
Stephen C

2
@Stephen C: แน่นอน! แต่อย่างที่ @Uri ชี้ให้เห็นฉันต้องแก้ปัญหาสองปัญหาที่แตกต่างกันด้วยความคลุมเครือของคำถาม :) นอกจากนี้ฉันไม่ค่อยใช้matches(): สำหรับประสิทธิภาพฉันมักจะเก็บไว้Patternในไฟล์final static. จ่ายออกหากรหัสเดียวกันทำงานบ่อย
Carl Smotricz

3
@Andreas_D: หึฉันได้รับคำสั่งแล้ว! OP บอกว่าเขาต้องการตรวจสอบสตริงหรืออาร์เรย์ถ่านเขาไม่เคยพูดอะไรเกี่ยวกับ nulls! :) * ตรวจสอบลายละเอียดในสัญญา * " nullไม่ใช่สตริง!"
Carl Smotricz

1
นอกจากนี้ "\\ w" จะจับคู่เฉพาะส่วนย่อยที่ จำกัด ของอักขระที่ไม่ใช่ช่องว่างแทนที่จะเป็นช่องว่างทั้งหมดเนื่องจากหมายถึง "อักขระคำ" ที่กำหนดเป็น AZ, az, 0-9 และขีดล่าง
Rob Raisch

2
ฉันใช้ your_string.trim () isEmpty () และทำงานให้ฉัน
Neri

59

ฉันจะใช้ไลบรารี Apache Commons Lang มีคลาสที่เรียกว่า StringUtils ซึ่งมีประโยชน์สำหรับการดำเนินการ String ทุกประเภท สำหรับการตรวจสอบว่า String ไม่ใช่ช่องว่างทั้งหมดหรือไม่คุณสามารถใช้สิ่งต่อไปนี้:

StringUtils.isBlank(<your string>)

นี่คือข้อมูลอ้างอิง: StringUtils.isBlank


8
ฉันชอบวิธีแก้ปัญหานี้มากกว่าการใช้คำตอบที่เลือก นอกจากนี้ยังจะตรวจสอบสตริง == null
Richard

ขณะนี้ไม่ถูกต้อง StringUtils.isEmptyตอนนี้จะแสดงผลเท็จหากคุณผ่าน ""
James Spence

53

สั้นกว่าที่ Carl Smotricz กล่าวถึงเล็กน้อย:

!string.trim().isEmpty();

10
คุณนักต้มตุ๋นรุ่นเยาว์และเคล็ดลับหลัง Java-1.6 ใหม่ของคุณ! อย่างจริงจังอย่างน้อยหนึ่งโครงการใน บริษัท ของฉันยังคงทำงานบน Java 1.4 (ถอนหายใจ)
Carl Smotricz

สั้นกว่า? ใช่. โดยส่วนตัวแล้วฉันชอบรูปแบบการเข้ารหัสแบบละเอียดมากขึ้น
Michel


9

หากคุณใช้Java 11isBlankวิธีการสตริงใหม่จะมีประโยชน์:

!s.isBlank();

หากคุณใช้Java 8, 9 หรือ 10คุณสามารถสร้างสตรีมง่ายๆเพื่อตรวจสอบว่าสตริงไม่ใช่ช่องว่างเท่านั้น:

!s.chars().allMatch(Character::isWhitespace));

นอกเหนือจากการไม่ต้องการไลบรารีของบุคคลที่สามเช่น Apache Commons Lang แล้วโซลูชันเหล่านี้ยังมีข้อได้เปรียบในการจัดการอักขระพื้นที่สีขาวและไม่ใช่แค่' 'ช่องว่างธรรมดาเช่นเดียวกับtrimโซลูชันที่อ้างอิงตามคำตอบอื่น ๆ อีกมากมาย คุณสามารถอ้างถึงJavadocsเพื่อดูรายการประเภทพื้นที่สีขาวที่รองรับทั้งหมด โปรดทราบว่าสตริงว่างจะครอบคลุมในทั้งสองกรณีด้วย


5
if(target.matches("\\S")) 
    // then string contains at least one non-whitespace character

หมายเหตุการใช้ back-slash cap-S หมายถึง "non-whitespace char"

ฉันจะเดิมพันว่านี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด (และอาจเร็วที่สุด?)


2
ลองดู: String year="1995"; year.matches("\\S"); will return falseนี่ไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง : |
Nhat Dinh

6
คุณพูดถูกแล้วแม้ว่าฉันจะสูญเสียเพื่ออธิบายว่าทำไม ตามเอกสาร Java String.matches จะตรวจสอบว่าสตริงที่ระบุตรงกับ regex หรือไม่ การทดลองเล็กน้อยแสดงให้เห็นว่าสิ่งนี้ไม่ถูกต้องทั้งหมดเนื่องจากฟังก์ชันนี้ดูเหมือนจะจับคู่เฉพาะเมื่อ regex ที่ให้มาตรงกับสตริงทั้งหมดเท่านั้น! ดังนั้นการเปลี่ยน regex ด้านบน ("\\ S") เป็น "^. * \\ S. * $" จะได้ผลตามที่คาดไว้แม้ว่าพฤติกรรมนี้จะไม่ได้รับการบันทึกไว้อย่างถูกต้องและดูเหมือนจะแตกต่างอย่างมากจากการใช้งานการจับคู่สตริงอื่น ๆ ใช้นิพจน์ทั่วไป
Rob Raisch

4

คำตอบนี้มุ่งเน้นไปที่ข้อความข้างต้น " ie มีอักขระที่เป็นตัวอักษรและตัวเลขอย่างน้อยหนึ่งตัว " นอกจากนั้นมันไม่ได้เพิ่มมากเกินไปที่อื่น ๆ (ก่อน) วิธีการแก้ปัญหายกเว้นว่ามันไม่ได้ทำร้ายคุณกับ NPE nullในกรณีที่เป็นสตริง

เราต้องการให้false(1) s เป็นnullหรือ (2) s ว่างเปล่าหรือ (3) มีเฉพาะไวท์คาร์

public static boolean containsNonWhitespaceChar(String s) {
  return !((s == null) || "".equals(s.trim()));
}

4

หากคุณกำลังตรวจสอบเฉพาะช่องว่างและไม่สนใจเรื่อง null คุณสามารถใช้ org.apache.commons.lang.StringUtils.isWhitespace (String str)

StringUtils.isWhitespace(String str);

(ตรวจสอบว่าสตริงมีเฉพาะช่องว่างหรือไม่)

หากคุณต้องการตรวจสอบค่าว่าง (รวมถึงช่องว่าง) ด้วย

StringUtils.isBlank(String str);

แนะนำให้ใช้ isBlank (String) เนื่องจากจัดการกับการตรวจสอบความถูกต้องเป็นโมฆะด้วย!
Sachidananda Naik

2

ด้วย Java-11 + คุณสามารถใช้String.isBlankAPI เพื่อตรวจสอบว่าสตริงที่กำหนดไม่ได้ประกอบด้วยช่องว่างทั้งหมดหรือไม่ -

String str1 = "    ";
System.out.println(str1.isBlank()); // made up of all whitespaces, prints true

String str2 = "    a";
System.out.println(str2.isBlank()); // prints false

javadoc เหมือนกันคือ:

/**
 * Returns {@code true} if the string is empty or contains only
 * {@link Character#isWhitespace(int) white space} codepoints,
 * otherwise {@code false}.
 *
 * @return {@code true} if the string is empty or contains only
 *         {@link Character#isWhitespace(int) white space} codepoints,
 *         otherwise {@code false}
 *
 * @since 11
 */
public boolean isBlank()

1

วิธีการตัดแต่งควรได้ผลดีสำหรับคุณ

http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/lang/String.html#trim ()

ส่งคืนสำเนาของสตริงโดยเว้นช่องว่างนำหน้าและต่อท้าย หากอ็อบเจ็กต์ String นี้แสดงถึงลำดับอักขระว่างหรืออักขระตัวแรกและตัวสุดท้ายของลำดับอักขระที่แสดงโดยอ็อบเจ็กต์ String นี้มีรหัสมากกว่า "\ u0020" (อักขระเว้นวรรค) การอ้างอิงถึงอ็อบเจ็กต์ String นี้จะถูกส่งกลับ

มิฉะนั้นหากไม่มีอักขระที่มีรหัสที่มากกว่า "\ u0020" ในสตริงจะมีการสร้างและส่งคืนอ็อบเจ็กต์ String ใหม่ที่เป็นตัวแทนของสตริงว่าง

มิฉะนั้นให้ k เป็นดัชนีของอักขระตัวแรกในสตริงที่มีรหัสมากกว่า "\ u0020" และให้ m เป็นดัชนีของอักขระสุดท้ายในสตริงที่มีรหัสมากกว่า "\ u0020" สร้างอ็อบเจ็กต์ String ใหม่ซึ่งแสดงถึงสตริงย่อยของสตริงนี้ที่ขึ้นต้นด้วยอักขระที่ดัชนี k และลงท้ายด้วยอักขระที่ดัชนี m นั่นคือผลลัพธ์ของ this.substring (k, m + 1)

วิธีนี้อาจใช้เพื่อตัดช่องว่างจากจุดเริ่มต้นและจุดสิ้นสุดของสตริง ในความเป็นจริงมันจะจดจ้องอักขระควบคุม ASCII ทั้งหมดด้วย

ส่งคืน: สำเนาของสตริงนี้โดยลบช่องว่างนำหน้าและต่อท้ายออกหรือสตริงนี้หากไม่มีช่องว่างนำหน้าหรือต่อท้ายช่องว่างสีขาวนำหรือต่อท้าย

คุณสามารถตัดแต่งแล้วเปรียบเทียบกับสตริงว่างหรืออาจตรวจสอบความยาวเป็น 0


ลิงก์ในคำตอบตาย - 404 | ขออภัยหน้าไม่อยู่หรือไม่สามารถใช้ได้อีก
ปาง

1

เพียงแค่การเปรียบเทียบประสิทธิภาพบน openjdk 13, Windows 10 สำหรับแต่ละข้อความ:

"abcd"
"    "
" \r\n\t"
" ab "
" \n\n\r\t   \n\r\t\t\t   \r\n\r\n\r\t \t\t\t\r\n\n"
"lorem ipsum dolor sit amet  consectetur adipisici elit"
"1234657891234567891324569871234567891326987132654798"

ดำเนินการทดสอบอย่างใดอย่างหนึ่งต่อไปนี้:

// trim + empty
input.trim().isEmpty()

// simple match
input.matches("\\S")

// match with precompiled pattern
final Pattern PATTERN = Pattern.compile("\\S");
PATTERN.matcher(input).matches()

// java 11's isBlank
input.isBlank()

แต่ละ 10.000.000 ครั้ง

ผลลัพธ์:

METHOD    min   max   note
trim:      18   313   much slower if text not trimmed
match:   1799  2010   
pattern:  571   662   
isBlank:   60   338   faster the earlier hits the first non-whitespace character

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

แก้ไข: ยิ่งข้อความยาวตัวเลขก็ยิ่งแตกต่างกัน การตัดแต่งข้อความขนาดยาวใช้เวลานานกว่าการวนซ้ำแบบธรรมดา อย่างไรก็ตาม regex ยังคงเป็นวิธีแก้ปัญหาที่ช้าที่สุด


0

ทางเลือก:

boolean isWhiteSpaces( String s ) {
    return s != null && s.matches("\\s+");
 }

1
\\ s * จะจับคู่สตริงทั้งหมดที่มีหรือไม่มีช่องว่าง บางทีคุณอาจหมายถึง \\ s +?
Rob Raisch

0

trim () และนิพจน์ทั่วไปอื่น ๆ ที่กล่าวถึงใช้ไม่ได้กับช่องว่างทุกประเภท

เช่น: Unicode Character 'LINE SEPARATOR' http://www.fileformat.info/info/unicode/char/2028/index.htm

ฟังก์ชัน Java Character.isWhitespace () ครอบคลุมทุกสถานการณ์

นั่นคือเหตุผลที่ ควรใช้โซลูชันStringUtils.isWhitespace (String) / หรือ StringUtils.isBlank (String) ที่กล่าวถึงแล้ว


0
StringUtils.isEmptyOrWhitespaceOnly(<your string>)

จะตรวจสอบ: - เป็นโมฆะ - เป็นเพียงช่องว่าง - เป็นสตริงว่างเปล่า ""

https://www.programcreek.com/java-api-examples/?class=com.mysql.jdbc.StringUtils&method=isEmptyOrWhitespaceOnly


1
นี่มาจากห้องสมุดใช่ไหม เชื่อมโยงไปยังโครงการ หรือสร้างใน Java? ระบุแพ็คเกจ
Basil Bourque

@BasilBourque ฉันคิดว่านี่คือ com.mysql.jdbc.StringUtils.isEmptyOrWhitespaceOnly
ahmet_y

0

ในขณะที่โดยส่วนตัวฉันจะเลือก!str.isBlank()ตามที่คนอื่น ๆ แนะนำไปแล้ว (หรือstr -> !str.isBlank()ในฐานะเพรดิเคต) วิธีการที่ทันสมัยและมีประสิทธิภาพมากกว่าที่str.trim()กล่าวถึงข้างต้นจะใช้str.strip()- โดยพิจารณาค่าว่างเป็น "ช่องว่าง":

if (str != null && str.strip().length() > 0) {...}

ตัวอย่างเช่น Predicate สำหรับใช้กับสตรีมเช่นในการทดสอบหน่วย:

@Test
public void anyNonEmptyStrippedTest() {
    String[] strings = null;
    Predicate<String> isNonEmptyStripped = str -> str != null && str.strip().length() > 0;
    assertTrue(Optional.ofNullable(strings).map(arr -> Stream.of(arr).noneMatch(isNonEmptyStripped)).orElse(true));
    strings = new String[] { null, "", " ", "\\n", "\\t", "\\r" };
    assertTrue(Optional.ofNullable(strings).map(arr -> Stream.of(arr).anyMatch(isNonEmptyStripped)).orElse(true));
    strings = new String[] { null, "", " ", "\\n", "\\t", "\\r", "test" };
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.