Scala expression to replace the file extension in a string

Here is the version I wrote using split:

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

This conversion, for example. foo.bar.coffee in foo.bar.js

What I like:

  • it works
  • it does not rely on things like indexOf()
  • it feels functional;)

What I do not like:

  • It is not as short as I hope.
  • this may confuse some readers.

How can I write an even simpler / simpler option?

UPDATE: Great answers below! In short:

  • it seems that my initial approach above was not bad, although it does not cover some corner cases, but it is a correction with a longer expression if you need to cover these
  • another, slightly shorter approach uses regular expressions that will be more or less readable depending on your regular expression background.
  • slightly shorter syntax for the original approach (angular cases not covered):

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

+7
source share
6 answers

I'm afraid that you really need to do this longer to do what is probably the most sensible thing:

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

It is unusual to lose the name of your file (at least if you are an end user)!

Let try regex:

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

I did not lose the file name, but there was also no extension. Ack.

Let me fix it:

 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 

Or with regex:

 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 

(Note the different behavior when the file name ends with a period.)

+9
source

Would a simple replacement for regular expressions do the trick?

how

 scala> "package.file.java".replaceAll("(\\.[^\\.]*$)", ".rb") scala> "package.file.rb" 
+3
source

You can always use replaceAll method on java.lang.String

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

It is shorter, but less readable.

+2
source

What happened to lastIndexOf?

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

Of course, if you want to save the file_name when it does not contain any period, you need to do a little more

 (if (fileName.contains('.')) fileName.take(fileName.lastIndexOf(".")) else fileName) + ".js" 
+2
source

So, I will go for speed here. As it happens, substring is a constant time because it just does not copy the string. Thus,

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

This uses a closure that will slow it down a bit. Faster:

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

EDIT: As this happens, Java now copies the string to substring .

+2
source

Very simple with lastIndexOf and work with a file name containing more than one dot

 def getFileNameWithoutExtension(fileName: String): String = { fileName.dropRight(fileName.length - fileName.lastIndexOf(".")) } val fileName = "foo.bar.coffee" getFileNameWithoutExtension(fileName) + ".js" 

The result is foo.bar.js

+2
source

All Articles