String.split
(Hangi çağrıların Pattern.split
) davranışı Java 7 ve Java 8 arasında değişir.
belgeleme
Belgelenmesi arasındaki karşılaştırılması Pattern.split
içinde Java 7 ve Java 8 , aşağıdaki maddeyi gözlemlemek eklenmektedir:
Giriş dizisinin başlangıcında pozitif genişlikli bir eşleşme olduğunda, sonuç dizisinin başlangıcına boş bir ana alt dize eklenir. Başlangıçta sıfır genişlikli bir eşleşme, ancak hiçbir zaman bu kadar boş bir alt dize üretmez.
Aynı maddesi de eklenir String.split
olarak Java 8 ile karşılaştırıldığında, Java 7 .
Referans uygulaması
Pattern.split
Java 7 ve Java 8'deki referans uygulamasının kodunu karşılaştıralım. Kod, 7u40-b43 ve 8-b132 sürümleri için grepcode'dan alınır.
Java 7
public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList<String> matchList = new ArrayList<>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Add remaining segment
if (!matchLimited || matchList.size() < limit)
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(0, resultSize).toArray(result);
}
Java 8
public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList<String> matchList = new ArrayList<>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
if (index == 0 && index == m.start() && m.start() == m.end()) {
// no empty leading substring included for zero-width match
// at the beginning of the input char sequence.
continue;
}
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Add remaining segment
if (!matchLimited || matchList.size() < limit)
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(0, resultSize).toArray(result);
}
Java 8'de aşağıdaki kodun eklenmesi, yukarıdaki davranışı açıklayan giriş dizesinin başlangıcındaki sıfır uzunluklu eşleşmeyi hariç tutar.
if (index == 0 && index == m.start() && m.start() == m.end()) {
// no empty leading substring included for zero-width match
// at the beginning of the input char sequence.
continue;
}
Uyumluluğun korunması
Java 8 ve sonraki sürümlerde aşağıdaki davranış
split
Sürümler arasında tutarlı ve Java 8'deki davranışla uyumlu davranmak için :
- Senin regex Eğer edebilirsiniz sıfır uzunluklu dize maç sadece eklemek
(?!\A)
de sonuna regex ve dışı yakalama grubundaki orijinal regex sarın (?:...)
(gerekirse).
- Senin regex Eğer edemez sıfır uzunluklu dize maç hiçbir şey yapmanız gerekmez.
- Normal ifadenin sıfır uzunluklu dizeyle eşleşip eşleşemeyeceğini bilmiyorsanız, 1. adımdaki her iki işlemi de yapın.
(?!\A)
dizenin dizenin başında bitmediğini kontrol eder, bu da eşleşmenin dizenin başında boş bir eşleşme olduğunu gösterir.
Java 7 ve önceki sürümlerde aşağıdaki davranış
split
Java 7 ile geriye dönük uyumlu hale getirmek için genel bir çözüm yoktur ve daha önce, split
kendi özel uygulamanıza işaret etmek için tüm örnekleri değiştirmenin kısası .
s.split("(?!^)")
işe yarıyor gibi görünüyor.