Scala正则表达式模式匹配的IP地址

时间:2015-10-08 07:08:25

标签: regex scala

我无法理解为什么这段代码会返回false:

      val reg = """.*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}).*""".r
      "ttt20.30.4.140ttt" match{
        case reg(one, two, three, four) =>
          if (host == one + "." + two + "." + three + "." + four) true else false
        case _ => false
      }

并且仅当我将其更改为:

  val reg = """.*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}).*""".r
  "20.30.4.140" match{
    case reg(one, two, three, four) =>
      if (host == one + "." + two + "." + three + "." + four) true else false
    case _ => false
  }

匹配

2 个答案:

答案 0 :(得分:3)

你的变种

def main( args: Array[String] ) : Unit = {
  val regex = """.*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}).*""".r
  val x = "ttt20.30.4.140ttt"

  x match {
    case regex(ip1,ip2,ip3,ip4) => println(ip1, ip2, ip3, ip4)
    case _ => println("No match.")
  }
}

匹配,但不是您想要的。结果将是(0,30,4,140)而不是( 20 ,30,4,140)。正如您所看到的,.*是贪婪的,所以消耗尽可能多的输入。

e.g。 ab12可以通过.*(\d{1,3})分隔为

  • ab12
  • ab12 ....这是选择的变体,因为.*消耗尽可能多的输入

解决方案

  1. .*不情愿(而不是贪婪),.*?总是如此

    """.*?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}).*""".r
    
  2. 在第一个数字之前精确定义模式,例如如果这些只是字符,请执行

    """[a-zA-Z]*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}).*""".r
    

答案 1 :(得分:1)

你应该使用不情愿的量词而不是贪婪的量词

14              mov r1, r4
(gdb) i r
r0             0x0      0
r1             0x0      0
r2             0x0      0
r3             0x0      0
r4             0xbefff8d6       3204446422
r5             0x3      3
r6             0x1      1
r7             0x0      0
r8             0xc      12
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
sp             0xbefff790       0xbefff790
lr             0x0      0
pc             0x8068   0x8068 <_start+20>
cpsr           0x10     16
(gdb) c
Continuing.

isbn-13 : 9780306406157: valid
Breakpoint 1, _start () at validate.s:12
12      0:      ldr r4, [sp, r8]
(gdb) stepi
13              add r8, r8, #4
(gdb)
14              mov r1, r4
(gdb) i r
r0             0x7      7
r1             0x8106   33030
r2             0x7      7
r3             0x0      0
r4             0x6176203a       1635131450
r5             0x3      3
r6             0x2      2
r7             0x4      4
r8             0x10     16
r9             0x809c   32924
r10            0x80ee   33006
r11            0x8106   33030
r12            0x81f4   33268
sp             0x80fa   0x80fa
lr             0x82f8   33528
pc             0x8068   0x8068 <_start+20>
cpsr           0x20000010       536870928