Разделение на пустую строку возвращает массив размером 1:
scala> "".split(',')
res1: Array[String] = Array("")
Учтите, что это возвращает пустой массив:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Пожалуйста, объясни :)
Разделение на пустую строку возвращает массив размером 1:
scala> "".split(',')
res1: Array[String] = Array("")
Учтите, что это возвращает пустой массив:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Пожалуйста, объясни :)
Ответы:
По той же причине, что
",test" split ','
и
",test," split ','
вернет массив размером 2. Все, что было до первого совпадения, возвращается как первый элемент.
"".split("wtf").length
возвращает 0. Только в JS это 1.: /
"," split ","
возвращает массив 0?
Если вы разделите апельсин ноль раз, у вас будет ровно один кусок - апельсин.
"orange".split(',')
, но, очевидно, не имеет отношения к разделению пустых строк. Если я разделю недостаток апельсина ноль раз, у меня все равно не будет апельсина; представляем ли мы это как пустой список без апельсинов, список из ровно одного без апельсина, список из двенадцати без апельсинов или что? Вопрос не в том, что у нас получается, а в том, как мы это представляем.
Методы разделения Java и Scala работают в два этапа, например:
",,,".split(",")
возвращается пустой массив.Согласно этому результату "".split(",")
должен быть пустой массив из-за второго шага, верно?
Должно. К сожалению, это искусственно созданный угловой случай. И это плохо, но , по крайней мере , это документировано в java.util.regex.Pattern
, если вы помните , чтобы взглянуть на документацию:
Для n == 0 результат такой же, как для n <0, за исключением того, что завершающие пустые строки не будут возвращены. (Обратите внимание, что случай, когда ввод сам по себе является пустой строкой, является особым, как описано выше, и параметр limit к нему не применяется.)
Итак, я советую вам всегда передавать n == -1
в качестве второго параметра (это пропустит шаг два выше), если вы не знаете конкретно, чего хотите достичь / вы уверены, что пустая строка не является тем, что ваша программа получит в качестве входных данных.
Если вы уже используете Guava в своем проекте, вы можете попробовать класс Splitter (документация) . Он имеет очень богатый API и упрощает понимание вашего кода.
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)
генерирует одноэлементный массив для n в (-1, 0, 1) с Oracle JDK 8. Было бы неплохо получить список только непустых токенов - думаю, может потребоваться полное регулярное выражение (что-то вроде "[^,\\s]+[^,]*[^,\\s]*"
).
Разделение пустой строки возвращает пустую строку в качестве первого элемента. Если в целевой строке не найден разделитель, вы получите массив размером 1, содержащий исходную строку, даже если она пуста.
",".split(",")
возвращает пустой массив.
Я знаю, что во всех языках программирования пустая строка остается действительной строкой. Таким образом, разделение с использованием любого разделителя всегда будет возвращать массив с одним элементом, где этот элемент является пустой строкой. Если бы это была пустая (не пустая) строка, это была бы другая проблема.
Это split
поведение унаследовано от Java, хорошо это или
плохо ... Scala не отменяет определение из String
примитива.
Обратите внимание, что вы можете использовать limit
аргумент для изменения поведения :
Параметр limit управляет количеством применений шаблона и, следовательно, влияет на длину результирующего массива. Если предел n больше нуля, то шаблон будет применен не более n - 1 раз, длина массива будет не больше n, а последняя запись массива будет содержать все входные данные за последним совпавшим разделителем. Если n не положительно, то шаблон будет применяться столько раз, сколько возможно, и массив может иметь любую длину. Если n равно нулю, шаблон будет применяться столько раз, сколько возможно, массив может иметь любую длину, а завершающие пустые строки будут отброшены.
то есть вы можете установить, limit=-1
чтобы получить поведение (всех?) других языков:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Кажется, хорошо известно, что поведение Java довольно запутано, но:
Вышеупомянутое поведение можно наблюдать, по крайней мере, от Java 5 до Java 8.
Была попытка изменить поведение, чтобы возвращать пустой массив при разделении пустой строки в JDK-6559590 . Однако вскоре он был возвращен в JDK-8028321, когда он вызывал регресс в различных местах. Это изменение никогда не попадает в первоначальную версию Java 8.
Примечание: метода разделения не было в Java с самого начала (его нет в 1.0.2 ), но фактически он присутствует как минимум в 1.4 (например, см. JSR51 около 2002 года). Я все еще расследую ...
Что неясно, так это то, почему Java выбрала это в первую очередь (я подозреваю, что изначально это была недосмотр / ошибка в «крайнем случае»), но теперь безвозвратно встроена в язык и поэтому остается .
"".split(",")
прежнему возвращает массив с одним элементом, например [""]
.
Пустая строка не имеет особого статуса при разделении строки. Вы можете использовать:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())