Tách trên một chuỗi trống trả về một mảng có kích thước 1:
scala> "".split(',')
res1: Array[String] = Array("")
Hãy xem xét rằng điều này trả về mảng trống:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Vui lòng giải thích :)
Tách trên một chuỗi trống trả về một mảng có kích thước 1:
scala> "".split(',')
res1: Array[String] = Array("")
Hãy xem xét rằng điều này trả về mảng trống:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Vui lòng giải thích :)
Câu trả lời:
Vì lý do tương tự mà
",test" split ','
và
",test," split ','
sẽ trả về một mảng có kích thước 2. Mọi thứ trước khi so khớp đầu tiên được trả về dưới dạng phần tử đầu tiên.
"".split("wtf").length
trả về 0. Chỉ trong JS là 1.: /
"," split ","
trả về mảng 0?
Nếu bạn chia một quả cam 0 lần, bạn có đúng một mảnh - quả cam.
"orange".split(',')
, nhưng rõ ràng không liên quan đến việc tách các chuỗi rỗng. Nếu tôi chia số thiếu màu cam của tôi bằng 0 lần, tôi vẫn không có quả cam; chúng ta có biểu thị điều đó dưới dạng danh sách trống không có quả cam, danh sách chính xác một quả không có quả cam, danh sách mười hai quả không có quả cam, hay là gì? Vấn đề không phải là chúng ta rốt cuộc là gì, mà là chúng ta đại diện cho nó như thế nào.
Phương pháp tách Java và Scala hoạt động theo hai bước như sau:
",,,".split(",")
trả về mảng trống.Theo điều này, kết quả của "".split(",")
phải là một mảng trống vì ở bước thứ hai, phải không?
Nó nên. Thật không may, đây là một trường hợp góc được giới thiệu nhân tạo. Và đó là xấu, nhưng ít nhất nó được ghi chép lại trong java.util.regex.Pattern
, nếu bạn nhớ để có một cái nhìn tại các tài liệu:
Đối với n == 0, kết quả giống như đối với n <0, ngoại trừ các chuỗi trống ở cuối sẽ không được trả về. (Lưu ý rằng trường hợp đầu vào là một chuỗi trống là đặc biệt, như được mô tả ở trên và tham số giới hạn không áp dụng ở đó.)
Vì vậy, tôi khuyên bạn nên luôn truyền n == -1
dưới dạng tham số thứ hai (điều này sẽ bỏ qua bước hai ở trên), trừ khi bạn biết cụ thể những gì bạn muốn đạt được / bạn chắc chắn rằng chuỗi trống không phải là thứ mà chương trình của bạn sẽ lấy làm đầu vào.
Nếu bạn đang sử dụng Guava trong dự án của mình, bạn có thể thử lớp Splitter (tài liệu) . Nó có một API rất phong phú và làm cho mã của bạn rất dễ hiểu.
Splitter.on(".").split(".a.b.c.") // "", "a", "b", "c", ""
Splitter.on(",").omitEmptyStrings().split("a,,b,,c") // "a", "b", "c"
Splitter.on(CharMatcher.anyOf(",.")).split("a,b.c") // "a", "b", "c"
Splitter.onPattern("=>?").split("a=b=>c") // "a", "b", "c"
Splitter.on(",").limit(2).split("a,b,c") // "a", "b,c"
"".split (",", n)
tạo một mảng một phần tử cho n trong (-1, 0, 1) bằng Oracle JDK 8. Sẽ rất tuyệt nếu chỉ nhận được danh sách các mã thông báo không trống - hãy đoán một regex đầy đủ có thể cần thiết (đại loại là "[^,\\s]+[^,]*[^,\\s]*"
).
Tách một chuỗi trống trả về chuỗi trống làm phần tử đầu tiên. Nếu không tìm thấy dấu phân tách trong chuỗi đích, bạn sẽ nhận được một mảng có kích thước 1 đang giữ chuỗi ban đầu, ngay cả khi nó trống.
",".split(",")
trả về mảng trống.
Trong tất cả các ngôn ngữ lập trình, tôi biết một chuỗi trống vẫn là một Chuỗi hợp lệ. Vì vậy, thực hiện phân tách bằng bất kỳ dấu phân tách nào sẽ luôn trả về một mảng phần tử duy nhất trong đó phần tử đó là Chuỗi trống. Nếu đó là một chuỗi null (không trống) thì đó sẽ là một vấn đề khác.
Đây split
hành vi được thừa hưởng từ Java, cho tốt hơn hoặc tồi tệ hơn ...
Scala không ghi đè lên các định nghĩa từ String
nguyên thủy.
Lưu ý rằng bạn có thể sử dụng limit
đối số để sửa đổi hành vi :
Tham số giới hạn kiểm soát số lần mẫu được áp dụng và do đó ảnh hưởng đến độ dài của mảng kết quả. Nếu giới hạn n lớn hơn 0 thì mẫu sẽ được áp dụng nhiều nhất n - 1 lần, độ dài của mảng sẽ không lớn hơn n và mục nhập cuối cùng của mảng sẽ chứa tất cả đầu vào vượt quá dấu phân cách được so khớp cuối cùng. Nếu n không dương thì mẫu sẽ được áp dụng nhiều lần nhất có thể và mảng có thể có độ dài bất kỳ. Nếu n bằng 0 thì mẫu sẽ được áp dụng nhiều lần nhất có thể, mảng có thể có độ dài bất kỳ và các chuỗi trống theo sau sẽ bị loại bỏ.
tức là bạn có thể đặt limit=-1
để có được hành vi của (tất cả?) các ngôn ngữ khác:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Có vẻ như ai cũng biết rằng hành vi của Java khá khó hiểu nhưng:
Hành vi trên có thể được quan sát từ ít nhất Java 5 đến Java 8.
Đã có nỗ lực thay đổi hành vi để trả về một mảng trống khi tách một chuỗi trống trong JDK-6559590 . Tuy nhiên, nó đã sớm được hoàn nguyên trong JDK-8028321 khi nó gây ra hồi quy ở nhiều nơi khác nhau. Thay đổi không bao giờ được đưa vào bản phát hành Java 8 đầu tiên.
Lưu ý: Phương pháp phân tách đã không có trong Java ngay từ đầu (nó không có trong 1.0.2 ) nhưng thực sự có từ ít nhất 1.4 (ví dụ: xem JSR51 khoảng năm 2002). Tôi vẫn đang điều tra ...
Điều không rõ ràng là tại sao Java lại chọn điều này ngay từ đầu (tôi nghi ngờ rằng nó ban đầu là một lỗi / lỗi trong "trường hợp cạnh"), nhưng bây giờ không thể thu hồi được đưa vào ngôn ngữ này và vì vậy nó vẫn còn .
"".split(",")
vẫn trả về một mảng phần tử như vậy [""]
.
Chuỗi rỗng không có trạng thái đặc biệt trong khi tách chuỗi. Bạn có thể sử dụng:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())