Split sur une chaîne vide renvoie un tableau de taille 1:
scala> "".split(',')
res1: Array[String] = Array("")
Considérez que cela renvoie un tableau vide:
scala> ",,,,".split(',')
res2: Array[String] = Array()
S'il vous plaît, expliquez :)
Split sur une chaîne vide renvoie un tableau de taille 1:
scala> "".split(',')
res1: Array[String] = Array("")
Considérez que cela renvoie un tableau vide:
scala> ",,,,".split(',')
res2: Array[String] = Array()
S'il vous plaît, expliquez :)
Réponses:
Pour la même raison que
",test" split ','
et
",test," split ','
renverra un tableau de taille 2. Tout ce qui se trouve avant la première correspondance est renvoyé comme premier élément.
"".split("wtf").lengthrenvoie 0. Seulement dans JS c'est 1.: /
"," split ","renvoie un tableau de 0?
Si vous divisez une orange zéro fois, vous avez exactement un morceau - l'orange.
"orange".split(','), mais n'est évidemment pas pertinente pour le fractionnement de chaînes vides. Si je divise mon manque d'orange zéro fois, je n'ai toujours pas d'orange; représentons-nous cela comme une liste vide de non-oranges, une liste d'exactement un non-orange, une liste de douze sans-oranges, ou quoi? Ce n'est pas une question de savoir avec quoi nous aboutissons, mais comment nous le représentons.
Les méthodes de fractionnement Java et Scala fonctionnent en deux étapes comme ceci:
",,,".split(",")renvoie un tableau vide.Selon cela, le résultat de "".split(",")devrait être un tableau vide à cause de la deuxième étape, non?
Cela devrait. Malheureusement, il s'agit d'un boîtier d'angle introduit artificiellement. Et c'est mauvais, mais au moins c'est documenté dans java.util.regex.Pattern, si vous vous souvenez de jeter un œil à la documentation:
Pour n == 0, le résultat est comme pour n <0, sauf que les chaînes vides de fin ne seront pas renvoyées. (Notez que le cas où l'entrée est elle-même une chaîne vide est spécial, comme décrit ci-dessus, et le paramètre limit ne s'applique pas là.)
Donc, je vous conseille de toujours passer n == -1comme deuxième paramètre (cela sautera l'étape deux ci-dessus), à moins que vous ne sachiez spécifiquement ce que vous voulez réaliser / vous êtes sûr que la chaîne vide n'est pas quelque chose que votre programme obtiendrait en entrée.
Si vous utilisez déjà Guava dans votre projet, vous pouvez essayer la classe Splitter (documentation) . Il possède une API très riche et rend votre code très facile à comprendre.
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)génère un tableau à un élément pour n dans (-1, 0, 1) avec Oracle JDK 8. Ce serait bien d'obtenir une liste de jetons non vides uniquement - supposons qu'une regex complète peut être nécessaire (quelque chose comme "[^,\\s]+[^,]*[^,\\s]*").
Le fractionnement d'une chaîne vide renvoie la chaîne vide comme premier élément. Si aucun délimiteur n'est trouvé dans la chaîne cible, vous obtiendrez un tableau de taille 1 qui contient la chaîne d'origine, même si elle est vide.
",".split(",")renvoie un tableau vide.
Dans tous les langages de programmation, je sais qu'une chaîne vide est toujours une chaîne valide. Donc, faire un fractionnement en utilisant n'importe quel délimiteur retournera toujours un tableau d'élément unique où cet élément est la chaîne vide. S'il s'agissait d'une chaîne nulle (et non vide), ce serait un problème différent.
Ce splitcomportement est hérité de Java, pour le meilleur ou pour le pire ...
Scala ne remplace pas la définition de la Stringprimitive.
Notez que vous pouvez utiliser l' limitargument pour modifier le comportement :
Le paramètre limit contrôle le nombre de fois où le motif est appliqué et affecte donc la longueur du tableau résultant. Si la limite n est supérieure à zéro, le modèle sera appliqué au plus n - 1 fois, la longueur du tableau ne sera pas supérieure à n et la dernière entrée du tableau contiendra toutes les entrées au-delà du dernier délimiteur correspondant. Si n n'est pas positif, le motif sera appliqué autant de fois que possible et le tableau peut avoir n'importe quelle longueur. Si n est égal à zéro, le motif sera appliqué autant de fois que possible, le tableau peut avoir n'importe quelle longueur et les chaînes vides de fin seront supprimées.
c'est-à-dire que vous pouvez définir le limit=-1pour obtenir le comportement de (tous?) autres langages:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Il semble bien connu que le comportement de Java est assez déroutant mais:
Le comportement ci-dessus peut être observé d'au moins Java 5 à Java 8.
Il y a eu une tentative de modification du comportement pour renvoyer un tableau vide lors du fractionnement d'une chaîne vide dans JDK-6559590 . Cependant, il a été rapidement rétabli dans JDK-8028321 lorsqu'il provoque une régression à divers endroits. Le changement ne fait jamais partie de la version initiale de Java 8.
Remarque: La méthode split n'était pas en Java depuis le début (ce n'est pas en 1.0.2 ) mais est en fait là depuis au moins 1.4 (par exemple voir JSR51 vers 2002). J'enquête toujours ...
Ce qui n'est pas clair, c'est pourquoi Java a choisi cela en premier lieu (je soupçonne que c'était à l'origine un oubli / bogue dans un "cas de pointe"), mais maintenant irrévocablement intégré dans le langage et il le reste .
"".split(",")renvoie toujours un tableau d'élément unique comme [""].
Les chaînes vides n'ont pas de statut spécial lors de la division d'une chaîne. Vous pouvez utiliser:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())