gpt4 book ai didi

regex - 如何在 Scala 中使用正则表达式进行匹配

转载 作者:行者123 更新时间:2023-12-02 19:48:39 24 4
gpt4 key购买 nike

我开始学习 Scala,并希望使用正则表达式来匹配字符串中的字符,以便我可以填充字符及其值(字符串值、数字等)的可变映射,然后打印结果。

我已经查看了 SO 上的几个答案并浏览了 Scala 文档,但似乎无法正确理解。我有一个简短的 Lexer 类,目前如下所示:

class Lexer {

private val tokens: mutable.Map[String, Any] = collection.mutable.Map()

private def checkCharacter(char: Character): Unit = {
val Operator = "[-+*/^%=()]".r
val Digit = "[\\d]".r
val Other = "[^\\d][^-+*/^%=()]".r
char.toString match {
case Operator(c) => tokens(c) = "Operator"
case Digit(c) => tokens(c) = Integer.parseInt(c)
case Other(c) => tokens(c) = "Other" // Temp value, write function for this
}
}

def lex(input: String): Unit = {
val inputArray = input.toArray
for (s <- inputArray)
checkCharacter(s)
for((key, value) <- tokens)
println(key + ": " + value)
}
}

我对那种奇怪的方法语法 Operator(c) 感到非常困惑,我看到它被用来处理要匹配的值,并且我也不确定这是否是在 Scala 中使用正则表达式的正确方法。我认为我想要这段代码做什么很清楚,我真的很感谢一些帮助理解这一点。如果需要更多信息,我会提供我能提供的信息

最佳答案

这个官方文档有很多例子:https://www.scala-lang.org/api/2.12.1/scala/util/matching/Regex.html 。可能令人困惑的是正则表达式的类型及其在模式匹配中的使用...

您可以使用.r从任何字符串构造正则表达式:

scala> val regex = "(something)".r
regex: scala.util.matching.Regex = (something)

您的正则表达式将成为一个对象,该对象具有一些有用的方法,可以找到匹配的组,例如findAllIn

在 Scala 中,惯用模式匹配来安全提取值,因此 Regex 类也有 unapplySeq 方法来支持模式匹配。这使得它成为 extractor object 。可以直接使用(不常见):

scala> regex.unapplySeq("something")
res1: Option[List[String]] = Some(List(something))

或者你可以让 Scala 编译器在你进行模式匹配时调用它:

scala> "something" match {
| case regex(x) => x
| case _ => ???
| }
res2: String = something

您可能会问为什么 unapply/unapplySeq 上有这个返回类型。该文档解释得很好:

The return type of an unapply should be chosen as follows:

If it is just a test, return a Boolean. For instance case even().
If it returns a single sub-value of type T, return an Option[T].
If you want to return several sub-values T1,...,Tn, group them in an optional tuple Option[(T1,...,Tn)].

Sometimes, the number of values to extract isn’t fixed and we would like to return an arbitrary number of values, depending on the input. For this use case, you can define extractors with an unapplySeq method which returns an Option[Seq[T]]. Common examples of these patterns include deconstructing a List using case List(x, y, z) => and decomposing a String using a regular expression Regex, such as case r(name, remainingFields @ _*) =>

简而言之,您的正则表达式可能匹配一个或多个组,因此您需要返回一个列表/序列。它必须包装在 Option 中以遵守提取器契约(Contract)。

您使用正则表达式的方式是正确的,我只是将您的函数映射到输入数组上以避免创建可变映射。也许是这样的:

class Lexer {

private def getCharacterType(char: Character): Any = {
val Operator = "([-+*/^%=()])".r
val Digit = "([\\d])".r
//val Other = "[^\\d][^-+*/^%=()]".r
char.toString match {
case Operator(c) => "Operator"
case Digit(c) => Integer.parseInt(c)
case _ => "Other" // Temp value, write function for this
}
}

def lex(input: String): Unit = {
val inputArray = input.toArray
val tokens = inputArray.map(x => x -> getCharacterType(x))
for((key, value) <- tokens)
println(key + ": " + value)
}
}

scala> val l = new Lexer()
l: Lexer = Lexer@60f662bd

scala> l.lex("a-1")
a: Other
-: Operator
1: 1

关于regex - 如何在 Scala 中使用正则表达式进行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58740642/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com