5

有一些字符串:

111/aaa
111/aaa|222/bbb

它们的表达形式为:

(.*)/(.*)(|(.*)/(.*))?

我试图用它来匹配一个字符串并提取值:

var rrr = """(.*)/(.*)(|(.*)/(.*))?""".r

"123/aaa|444/bbb" match {
    case rrr(pid,pname, cid,cname) => println(s"$pid, $pname, $cid, $cname")
    case _ => println("not matched ?!")
}

但它打印:

not matched ?!

我想得到:

123, aaa, 444, bbb

如何解决?


更新

感谢@BartKiers 和@Barmar 的分析器,我发现我的正则表达式有几个错误,终于找到了这个解决方案:

var rrr = """(.*?)/(.*?)([|](.*?)/(.*?))?""".r

"123/aaa|444/bbb" match {
    case rrr(pid,pname, _, cid,cname) => println(s"$pid, $pname, $cid, $cname")
    case _ => println("not matched ?!")
}

它有效,但你可以看到有一个_实际上没有用。有什么方法可以重新定义我可以写的正则表达式rrr(pid,pname,cid,cname)来匹配它?

4

2 回答 2

5

.*可能会导致很多回溯,因为.*会首先匹配完整的字符串,然后一个接一个地返回,直到匹配第一个/

此外,它不会像您期望的那样正确捕获组中的值..

你应该使用.*?

你的正则表达式应该是

^(.*?)/(.*?)(?:\|(.*?)/(.*?))?$

小字符串不会有任何性能差异,但它会捕获正确组中的值

注意?:正则表达式中的 ,这意味着不要捕获 group (?:\|(.*?)/(.*?))?。所以结果只有 4 个子组。

于 2013-07-05T07:02:27.377 回答
3

尝试转义|,这是正则表达式中的逻辑 OR:

var rrr = """(.*)/(.*)(\|(.*)/(.*))?""".r
于 2013-07-05T06:58:41.390 回答