Scala方法在不使用外部库的情况下解析命令行参数



我有一个小模块,需要使用可选参数解析命令行参数。

函数应该提取所需的参数,返回这些参数,并返回未在单独列表中指定的任何其他参数。

我发现这个函数运行得很好。还添加了一些scaladoc和一个规范来记录和测试

任何改进都会使其更加"完美";惯用的"?

模块:

import scala.collection.mutable.ListBuffer
object Utilities {
/**
* Parses command line arguments
*
* This function parses command line arguments from `args`, as
* an `Array[String]`.
* The parameters to be extracted can be prefixed with `-` as default or
* the param prefix in `paramFormat` (for example `--`) and passed in
* `parameters` as `List[String]`.
*
* The function returns a `Map[String, String]` with extracted parameters and a `List[String]` with remaining arguments that were not extracted.
*
* If a parameter does not contain a value and is followed with another parameter (with same prefix), it is ignored.
*
* Usage:
*
* {{{
* val args = Array( "-param1", "-wrong", "generated", "singleparam1", "singleparam2", "-anotherparam", "mydata", "-param2", "myboard" )
* val (params, remaininglargs) = ParseArguments(args, List("param1", "param2"))
* }}}
*
* Results:
* {{{
* Map("param2" -> "myboard")
* Array("-wrong", "generated", "singleparam1", "singleparam2", "-anotherparam", "mydata")
* }}}
*
* @param args the input arguments
* @param parameters the parameters to be extracted from input `args`.
* @param paramFormat the param prefix to be extracted (Eg. `-` or `--`).
* @return a `Map[String,String]` with extracted params and an `Array[String]` with remaining arguments.
*/
def ParseArguments(
args: Array[String],
parameters: List[String],
paramFormat: String = "-"
): (Map[String, String], Array[String]) = {
var params: Map[String, String] = Map()
var remainingArgs               = new ListBuffer[String]()
var lastKey                     = ""
for (key <- args.toList) {
key match {
// Below are the required module parameters
case p if parameters.contains(p.drop(paramFormat.length)) => lastKey = p.drop(paramFormat.length)
// Below are the extraction cases. No need to change.
case param if (lastKey.nonEmpty && param.slice(0, paramFormat.length) != paramFormat) =>
params += (lastKey -> param); lastKey = ""
case param if (lastKey.nonEmpty && param.slice(0, paramFormat.length) == paramFormat) =>
remainingArgs += param; lastKey = ""
case param if lastKey.isEmpty =>
remainingArgs += param; lastKey = ""
}
}
(params, remainingArgs.toArray)
}
}

规格:

import org.scalatest.flatspec._
import org.scalatest.matchers.should._
import Utilities._
class ParseArgumentsSpec extends AnyFlatSpec with Matchers {
"ParseArguments" should "parse one parameter" in {
val args                    = Array("-param1", "data1", "generated", "singleparam1")
val (params, remainingargs) = ParseArguments(args, List("param1", "param2"))
assert(params === Map("param1" -> "data1"))
assert(remainingargs === List("generated", "singleparam1"))
}
"ParseArguments" should "parse multiple parameters" in {
val args                    = Array("-param1", "data1", "generated", "-param2", "data2", "-anotherparam")
val (params, remainingargs) = ParseArguments(args, List("param1", "param2"))
assert(params === Map("param1" -> "data1", "param2" -> "data2"))
assert(remainingargs === List("generated", "-anotherparam"))
}
"ParseArguments" should "parse one parameter and ignore a wrong one" in {
val args                    = Array("-param1", "-wrong", "generated", "-anotherparam", "mydata", "-param2", "data2")
val (params, remainingargs) = ParseArguments(args, List("param1", "param2"))
assert(params === Map("param2" -> "data2"))
assert(remainingargs === List("-wrong", "generated", "-anotherparam", "mydata"))
}
"ParseArguments" should "parse one parameter with double dash('--')" in {
val args                    = Array("--param1", "data1", "generated", "--anotherparam", "mydata", "-param2", "data2")
val (params, remainingargs) = ParseArguments(args, List("param1", "param2"), "--")
assert(params === Map("param1" -> "data1"))
assert(remainingargs === List("generated", "--anotherparam", "mydata", "-param2", "data2"))
}
}

相关内容

最新更新