Scala 表达式替换字符串中的文件扩展名

发布于 2024-10-12 20:29:46 字数 648 浏览 2 评论 0原文

这是我使用 split 编写的版本:

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

它将例如 foo.bar.coffee 转换为 foo.bar.js

我喜欢的是:

  • 它有效,
  • 它不依赖于像 indexOf() 这样的东西,
  • 它感觉很实用;)

我不喜欢的是:

  • 它没有我希望的那么短
  • 一些读者感到困惑

,它可能会让 我可以写一个更简单/直接的版本吗?

更新:下面有很好的答案!简而言之:

  • 看起来我上面的原始方法还不错,尽管它没有涵盖一些极端情况,但是如果您需要覆盖
  • 另一种稍短的方法使用正则表达式,则可以使用更长的表达式来修复,这将是或多或少可读取决于您的正则表达式背景
  • 原始方法的稍短语法(未涵盖的极端情况)如下:

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

Here is a version I wrote using split:

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

This transforms e.g. foo.bar.coffee into foo.bar.js.

What I like:

  • it works
  • it doesn't rely on things like indexOf()
  • it feels functional ;)

What I don't like:

  • it's not as short as I would hope
  • it might confuse some readers

How can I write an even simpler / straightforward version?

UPDATE: Great answers below! In short:

  • seems like my original approach above was not bad although it doesn't cover some corner cases, but that's fixable with a longer expression if you need to cover those
  • another, slightly shorter approach uses regexps, which will be more or less readable depending on your regexp background
  • a slightly shorter syntax for the original approach (corner cases not covered) reads:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

西瓜 2024-10-19 20:29:46

恐怕您实际上必须让它更长来做可能是最明智的鲁棒事情:

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

有点意外地丢失了文件名(至少如果您是最终用户)!

让我们尝试一下正则表达式:

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

没有丢失文件名,但也没有扩展名。确认。

让我们修复它:

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

请注意文件名以句点结尾的极端情况的不同行为。)

I'm afraid you actually have to make it longer to do what is probably the most sensible robust thing:

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

Kinda unexpected to lose the name of your file (at least if you're an end user)!

Let's try regex:

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

Didn't lose the file name, but there's no extension either. Ack.

Let's 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 on the corner case where the filename ends with periods.)

我三岁 2024-10-19 20:29:46

简单的正则表达式替换可以解决问题吗?

喜欢:

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

Will a simple regex replacement do the trick?

Like:

scala> "package.file.java".replaceAll("(\\.[^\\.]*$)", ".rb") 
scala> "package.file.rb"
暮色兮凉城 2024-10-19 20:29:46

LastIndexOf 有什么问题吗?

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

当然,如果你想保留不包含任何点的文件名,你需要做更多的事情

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

What's wrong with lastIndexOf?

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

Of course if you want to keep the fileName when it doesn't contain any dot, you need to do a little bit more

(if (fileName.contains('.')) fileName.take(fileName.lastIndexOf(".")) 
else fileName) + ".js"
动次打次papapa 2024-10-19 20:29:46

使用lastIndexOf非常容易,并且可以处理包含多个点的文件名

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

val fileName = "foo.bar.coffee"

getFileNameWithoutExtension(fileName) + ".js"

结果是foo.bar.js

Very easy with lastIndexOf, and work with file name that contains more than one dot

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

val fileName = "foo.bar.coffee"

getFileNameWithoutExtension(fileName) + ".js"

Result is foo.bar.js

白色秋天 2024-10-19 20:29:46

您始终可以在 java.lang.String 上使用 replaceAll 方法,

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

它更短,但可读性较差。

You could always use the replaceAll method on java.lang.String

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

It's shorter but less readable.

时光磨忆 2024-10-19 20:29:46

所以,我会在这里追求速度。碰巧,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 上的字符串。

So, I'll go for speed here. As it happens, substring is constant time because it simply does not copy the string. So,

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

This uses a closure, which 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 it happens, Java now does copy the string on substring.

此生挚爱伱 2024-10-19 20:29:46

如果您知道当前的扩展名是什么,那么您可以这样做:

def replaceExtension(fileName: String, oldExt: String, newExt: String): String =
  fileName.stripSuffix(oldExt) + newExt

// Be sure to use `.` when calling:
replaceExtension(fileName, ".javascript", ".js")

If you know what the current extension is, then you could do this:

def replaceExtension(fileName: String, oldExt: String, newExt: String): String =
  fileName.stripSuffix(oldExt) + newExt

// Be sure to use `.` when calling:
replaceExtension(fileName, ".javascript", ".js")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文