斯卡拉正则表达式奇异性

时间:2014-06-13 00:01:05

标签: regex scala

我有这个正则表达式:

^(10)(1|0)(.)(.)(.)(.{18})((AB[^|]*)\||(AQ[^|]*)\||(AJ[^|]*)\||(AF[^|]*)\||(CS[^|]*)\||(CR[^|]*)\||(CT[^|]*)\||(CK[^|]*)\||(CV[^|]*)\||(CY[^|]*)\||(DA[^|]*)\||(AO[^|]*)\|)+AY([0-9]*)AZ(.*)$

为了给它一些组织,实际上有3个部分:

// Part 1
^(10)(1|0)(.)(.)(.)(.{18})

// Part 2
// Optional Elements that begin with two characters and is terminated by a |
// May appear at most once
((AB[^|]*)\||(AQ[^|]*)\||(AJ[^|]*)\||(AF[^|]*)\||(CS[^|]*)\||(CR[^|]*)\||(CT[^|]*)\||(CK[^|]*)\||(CV[^|]*)\||(CY[^|]*)\||(DA[^|]*)\||(AO[^|]*)\|)+

// Part 3
AY([0-9]*)AZ(.*)$

第2部分是我遇到问题的部分,但我相信当前的正则表达式表示这些给定元素中的任何一个都会出现一次或多次。我可以做类似的事情:(AB.*?|)但我不需要在我的小组中使用管道,并且不太确定如何表达它。

这是我的样本输入 - 如果您之前已经看过它,那么它是SIP2(请忽略校验和,我知道它无效):

101YNY201406120000091911AOa|ABb|AQc|AJd|CKe|AFf|CSg|CRh|CTi|CVj|CYk|DAl|AY1AZAA71

这是我的Scala代码片段:

val regex = """^(10)(1|0)(.)(.)(.)(.{18})((AB[^|]*)\||(AQ[^|]*)\||(AJ[^|]*)\||(AF[^|]*)\||(CS[^|]*)\||(CR[^|]*)\||(CT[^|]*)\||(CK[^|]*)\||(CV[^|]*)\||(CY[^|]*)\||(DA[^|]*)\||(AO[^|]*)\|)+AY([0-9]*)AZ(.*)$""".r
val msg = "101YNY201406120000091911AOa|ABb|AQc|AJd|CKe|AFf|CSg|CRh|CTi|CVj|CYk|DAl|AY1AZAA71"
val m = regex.findFirstMatchIn(msg)) match {
  case None => println("No match")
  case Some(x) =>
    for (i <- 0 to x.groupCount) {
      println(i + " " + x.group(i))
    }
}

这是我的输出:

0 101YNY201406120000091911AOa|ABb|AQc|AJd|CKe|AFf|CSg|CRh|CTi|CVj|CYk|DAl|AY1AZAA71
1 10
2 1
3 Y
4 N
5 Y
6 201406120000091911
7 DAl|
8 ABb
9 AQc
10 AJd
11 AFf
12 CSg
13 CRh
14 CTi
15 CKe
16 CVj
17 CYk
18 DAl
19 AOa
20 1
21 AA71

请注意以7开头的条目。任何人都可以解释为什么会出现这种情况吗?

我使用的是Scala 2.10.4,但我相信Scala中的正则表达式只是使用Java的正则表达式。我当然愿意接受其他解析字符串的建议。

编辑:基于wingedsubmariner的回复,我能够修正我的正则表达式:

^(10)(1|0)(.)(.)(.)(.{18})(?:AB([^|]*)\||AQ([^|]*)\||AJ([^|]*)\||AF([^|]*)\||CS([^|]*)\||CR([^|]*)\||CT([^|]*)\||CK([^|]*)\||CV([^|]*)\||CY([^|]*)\||DA([^|]*)\||AO([^|]*)\|)+AY([0-9]*)AZ(.*)$

基本上添加?:表示我对该群组不感兴趣!

1 个答案:

答案 0 :(得分:2)

每个括号中都有一个匹配的组,顺序是正则表达式中左括号的顺序。匹配组7对应于开始您的&#34;组2&#34;:

的左括号
((AB[^|]*)\||(AQ[^|]*)\||(AJ[^|]*)\||(AF[^|]*)\||(CS[^|]*)\||(CR[^|]*)\||(CT[^|]*)\||(CK[^|]*)\||(CV[^|]*)\||(CY[^|]*)\||(DA[^|]*)\||(AO[^|]*)\|)+
^
|
This parenthesis

每个匹配的组都采用匹配的文本的最后部分的值,在这种情况下是DAl|,因为它是与#34;组2&#34;匹配的最后一段文本。表达

这是一个演示行为的简单示例:

val regex = """((A)\||(B)\|)+""".r
val msg = "A|B|A|B|"
regex.findFirstMatchIn(msg) match {
  case None => println("No match")
  case Some(x) =>
    for (i <- 0 to x.groupCount) {
      println(i + " " + x.group(i))
    }
}

产生:

0 A|B|A|B|
1 B|
2 A
3 B