Scala:匹配可选的正则表达式组

16

我正在尝试使用以下代码在 Scala 2.8(beta 1)中匹配选项组:

import scala.xml._

val StatementPattern = """([\w\.]+)\s*:\s*([+-])?(\d+)""".r

def buildProperty(input: String): Node = input match {
    case StatementPattern(name, value) => <propertyWithoutSign />
    case StatementPattern(name, sign, value) => <propertyWithSign />
}

val withSign = "property.name: +10"
val withoutSign = "property.name: 10"

buildProperty(withSign)        // <propertyWithSign></propertyWithSign>
buildProperty(withoutSign)     // <propertyWithSign></propertyWithSign>

但是这样不起作用。匹配可选的正则表达式组的正确方法是什么?

2个回答

26

如果可选组未匹配,则它将为null,因此您需要在模式匹配中包含"null":

import scala.xml._

val StatementPattern = """([\w\.]+)\s*:\s*([+-])?(\d+)""".r

def buildProperty(input: String): Node = input match {
    case StatementPattern(name, null, value) => <propertyWithoutSign />
    case StatementPattern(name, sign, value) => <propertyWithSign />
}

val withSign = "property.name: +10"
val withoutSign = "property.name: 10"

buildProperty(withSign)        // <propertyWithSign></propertyWithSign>
buildProperty(withoutSign)     // <propertyWithSign></propertyWithSign>

1
Scala 在 Regex.unapplySeq 中使用 Matcher.group 方法。这表明如果某个组无法匹配序列的一部分,则返回 null。- http://java.sun.com/javase/6/docs/api/java/util/regex/Matcher.html#group(int) - Ben Lings
4
Scala最好能够使用Option类作为可选的正则表达式字段,而不是要求进行空值检查。 - Rob Wilton
“case语句”的顺序很重要:匹配null的语句应该首先列出,否则sign变量将包含null。” - dr jerry

0

我认为你的正则表达式没有问题。虽然在字符类中不需要转义.

编辑:

你可以尝试类似这样的代码:

([\w.]+)\s*:\s*((?:+|-)?\d+)

捕获名称和值,其中值可以具有可选符号。


@codaddict 谢谢你指出来;) 正则表达式是好的,问题是我无法使用Scala模式匹配系统找到可选组如何匹配。 我在网上找不到任何例子来解决这个问题。 - BefittingTheorem
@codaaddict 谢谢,这会让我的代码工作起来,但是Scala模式匹配问题仍然存在 :) 实际上,我需要基于是否有符号而不同的XML,因此使用模式匹配系统来提取并测试是否有符号似乎是最清晰的解决方案。 - BefittingTheorem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接