【问题标题】:How to do a case insensitive match for command line arguments in scala?如何在scala中对命令行参数进行不区分大小写的匹配?
【发布时间】:2020-09-28 14:39:47
【问题描述】:

我正在开发一个用 Scala 编写的命令行工具,它的执行方式如下:

sbt "run --customerAccount 1234567"

现在,我希望可以灵活地接受 "--CUSTOMERACCOUNT"--cUsToMerAccount--customerACCOUNT ...你明白了

代码如下:

lazy val OptionsParser: OptionParser[Args] = new scopt.OptionParser[Args]("scopt") {
    head(
      "XML Generator",
      "Creates XML for testing"
    )
    help("help").text(s"Prints this usage message. $envUsage")

    opt[String]('c', "customerAccount")
      .text("Required: Please provide customer account number as -c 12334 or --customerAccount 12334")
      .required()
      .action { (cust, args) =>
        assert(cust.nonEmpty, "cust is REQUIRED!!")
        args.copy(cust = cust)
      }
}

我假设opt[String]('c', "customerAccount") 从命令行进行模式匹配并将与“customerAccount”匹配 - 我如何让它与"--CUSTOMERACCOUNT"--cUsToMerAccount--customerACCOUNT 匹配? args.copy (cust = cust) 到底是做什么的?

如果这些问题看起来太基本,我深表歉意。我对 Scala 非常陌生,之前曾在 Java 和 Python 中工作过,所以有时我也觉得语法有点难以理解。

【问题讨论】:

  • 你的问题似乎与 scopt 库有关,而不是一般的 scala,我会从 scopt 文档开始,看看它是否支持你需要的东西

标签: scala command-line-interface scopt


【解决方案1】:

您通常会使用以下代码解析 args:

OptionsParser.parse(args, Args())

因此,如果您想要不区分大小写,可能最简单的方法是规范化 args 的大小写,例如

val canonicalized = args.map(_.toLowerCase)

OptionsParser.parse(canonicalized, Args())

或者,例如,如果您只想规范化以 -- 开头且在裸 -- 之前的 args:

val canonicalized =
  args.foldLeft(false -> List.empty[String]) { (state, arg) =>
    val (afterDashes, result) = state
    if (afterDashes) true -> (arg :: result)  // pass through unchanged
    else {
      if (arg == "==") true -> (arg :: result) // move to afterDash state & pass through
      else {
        if (arg.startsWith("--")) false -> (arg.toLowerCase :: result)
        else false -> (arg :: result) // pass through unchanged
      }
    }
  }
  ._2    // Extract the result
  .reverse // Reverse it back into the original order (if building up a sequence, your first choice should be to build a list in reversed order and reverse at the end)

  OptionsParser.parse(canonicalized, Args())

关于第二个问题,因为Args(几乎可以肯定)是case class,它有一个copy 方法,该方法用(很可能,取决于使用情况)其字段的不同值构造一个新对象。所以

 args.copy(cust = cust)

创建一个新的Args 对象,其中:

  • 该对象中cust 字段的值是该块中cust 变量的值(这基本上是一种巧妙的技巧,适用于命名方法参数)
  • 其他字段的值取自args

【讨论】:

  • 这非常有帮助,谢谢您的好心先生!我对cust = cust 感到困惑,因为乍一看它们看起来和暗示相同。来自 java 背景,我更喜欢this.cust = cust 以获得更好的可读性。我想我会用 caconicalizing args 的情况来看看它是如何建立起来的!感谢一百万您的回答! :)
猜你喜欢
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 2016-06-13
  • 1970-01-01
  • 2018-11-10
  • 2018-11-04
相关资源
最近更新 更多