Scala выражение для замены расширения файла в строке - PullRequest
9 голосов
/ 19 января 2011

Вот версия, которую я написал с использованием split:

fileName.split('.').init ++ Seq("js") mkString "."

Это преобразуется, например, foo.bar.coffee в foo.bar.js.

Что мне нравится:

  • работает
  • это не зависит от таких вещей, как indexOf()
  • это чувствует себя функционально;)

Что мне не нравится:

  • это не так коротко, как хотелось бы надеяться
  • это может смутить некоторых читателей

Как мне написать еще более простую / понятную версию?

ОБНОВЛЕНИЕ: отличные ответы ниже! Короче говоря:

  • кажется, что мой оригинальный подход выше был неплохим, хотя он не охватывает некоторые угловые случаи, но это можно исправить с помощью более длинного выражения, если вам нужно охватить эти
  • другой, немного более короткий подход использует регулярные выражения, которые будут более или менее читабельными в зависимости от вашего фона регулярных выражений
  • немного более короткий синтаксис для исходного подхода (угловые случаи не охвачены):

    fileName.split('.').init :+ "js" mkString "."

Ответы [ 6 ]

10 голосов
/ 19 января 2011

Боюсь, вам действительно нужно сделать это длиннее , чтобы сделать то, что, пожалуй, самая разумная и надежная вещь:

scala> "oops".split('.').init ++ Seq("js") mkString "."  
res0: String = js

Какая-то неожиданная потеря названия вашего файла (по крайней мере, если вы конечный пользователь)!

Давайте попробуем регулярное выражение:

scala> "oops".replaceAll("\\.[^.]*$", ".js")
res1: java.lang.String = oops

Не потерял имя файла, но расширения тоже нет. Ack.

Давайте исправим это:

def extensor(orig: String, ext: String) = (orig.split('.') match {
  case xs @ Array(x) => xs
  case y => y.init
}) :+ "js" mkString "."

scala> extensor("oops","js")
res2: String = oops.js

scala> extensor("oops.txt","js")
res3: String = oops.js

scala> extensor("oops...um...","js")
res4: String = oops...js

Или с регулярным выражением:

scala> "oops".replaceAll("\\.[^.]*$", "") + ".js" 
res5: java.lang.String = oops.js

scala> "oops.txt".replaceAll("\\.[^.]*$", "") + ".js"
res6: java.lang.String = oops.js

scala> "oops...um...".replaceAll("\\.[^.]*$", "") + ".js"
res7: java.lang.String = oops...um...js

(Обратите внимание на различное поведение в угловом случае, когда имя файла заканчивается точками.)

3 голосов
/ 19 декабря 2016

Очень просто с lastIndexOf и работать с именем файла, содержащим более одной точки

def getFileNameWithoutExtension(fileName: String): String = {
  fileName.dropRight(fileName.length - fileName.lastIndexOf("."))
}

val fileName = "foo.bar.coffee"

getFileNameWithoutExtension(fileName) + ".js"

Результат - foo.bar.js

3 голосов
/ 19 января 2011

Что не так с lastIndexOf?

fileName.take(1 + fileName.lastIndexOf(".")) + "js"

Конечно, если вы хотите сохранить fileName, когда он не содержит никакой точки, вам нужно сделать немного больше

(if (fileName.contains('.')) fileName.take(fileName.lastIndexOf(".")) 
else fileName) + ".js"
3 голосов
/ 19 января 2011

Сработает ли простая замена регулярных выражений?

Как:

scala> "package.file.java".replaceAll("(\\.[^\\.]*$)", ".rb") 
scala> "package.file.rb"
2 голосов
/ 19 января 2011

Итак, я пойду на скорость здесь.Как это бывает, substring - это постоянное время, потому что оно просто не копирует строку.Итак,

((index: Int) => (
) + ".js")(fileName lastIndexOf '.')

Это использует замыкание, которое немного замедлит его.Быстрее:

def addJS(fileName: String) = {
    def addJSAt(index: Int) = (
        if (index >= 0) fileName substring (0, index) 
        else fileName
    ) + ".js"

    addJSAt(fileName lastIndexOf '.')
}

РЕДАКТИРОВАТЬ: Как это происходит, Java теперь копирует строку на substring.

2 голосов
/ 19 января 2011

Вы всегда можете использовать метод replaceAll для java.lang.String

scala> "foo.bar.coffee".replaceAll("\\.[^.]*$", ".js")
res11: java.lang.String = foo.bar.js

Это короче, но менее читабельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...