Разделение на пустую строку возвращает массив размером 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. Все, прежде чем первое совпадение будет возвращено в качестве первого элемента.
Если вы разделите оранжевое нулевое время, у вас будет ровно одна часть - оранжевая.
Разделение пустой строки возвращает пустую строку в качестве первого элемента. Если разделитель не найден в целевой строке, вы получите массив размером 1, который содержит исходную строку, даже если она пуста.
Методы разделения Java и Scala работают в два этапа, например:
",,".split(",")
возвращает пустой массив. Согласно этому результат "".split(",")
должен быть пустым массивом из-за второго шага, верно?
Должно. К сожалению, это искусственно введенный угловой корпус. И это плохо, но, по крайней мере, это java.util.regex.Pattern
в 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"
"a".split(",")
→ "a"
следовательно
"".split(",")
→ ""
Во всех языках программирования я знаю, что пустая строка по-прежнему является действительной строкой. Таким образом, разделение с использованием любого разделителя всегда будет возвращать один массив элементов, где этот элемент является пустой строкой. Если это был пустой (не пустой) String, это было бы другой проблемой.
Это split
поведение наследуется от Java, к лучшему или худшему...
Scala не переопределяет определение из примитива String
.
Обратите внимание, что вы можете использовать аргумент 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.
Примечание. Метод split не был в Java с самого начала (он не в версии 1.0.2), но на самом деле существует менее 1,4 (например, см. JSR51 около 2002 г.). Я все еще расследую...
Непонятно, почему Java выбрала это в первую очередь (мое подозрение в том, что это изначально было недосмотр/ошибка в "краевом случае" ), но теперь безвозвратно запекается на этом языке, и поэтому он остается.
Пустая строка не имеет специального статуса при разбиении строки. Вы можете использовать:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())
Вы можете использовать следующее ниже, чтобы вернуть пустую строку.
String[] files = new String[0];