模式匹配提取String Scala

时间:2017-04-24 06:23:17

标签: regex scala pattern-matching

我想提取一个与我定义的两个正则表达式模式匹配的String的一部分:

  //should match R0010, R0100,R0300 etc 
  val rPat="[R]{1}[0-9]{4}".r
  // should match P.25.01.21 , P.27.03.25 etc
  val pPat="[P]{1}[.]{1}[0-9]{2}[.]{1}[0-9]{2}[.]{1}[0-9]{2}".r 

当我现在定义我的方法来提取元素时:

  val matcher= (s:String) => s match {case pPat(el)=> println(el) // print the P.25.01.25
                                        case rPat(el)=>println(el) // print R0100 
                                        case _ => println("no match")}

用例如:

进行测试
  val pSt=" P.25.01.21 - Hello whats going on?"
  matcher(pSt)//prints "no match" but should print P.25.01.21
  val rSt= "R0010  test test 3,870" 
  matcher(rSt) //prints also "no match" but should print R0010
  //check if regex is wrong
  val pHead="P.25.01.21"
  pHead.matches(pPat.toString)//returns true
  val rHead="R0010"
  rHead.matches(rPat.toString)//return true

我不确定正则表达式是否错误,但匹配方法是否适用于元素。那么这种方法有什么问题呢?

3 个答案:

答案 0 :(得分:2)

当您使用与字符串匹配的模式时,您需要记住:

  • 您传递的.r模式需要匹配整个字符串,否则将不会返回匹配项(解决方案是创建模式.r.unanchored
  • 一旦您将其取消隐藏,请注意不需要的匹配:R[0-9]{4}将与R1234中的CSR123456匹配(解决方案根据您的实际要求而有所不同,通常是字边界{{ 1}}足够,或者可以使用负lookarounds
  • \b块内,如果您想要获取某些值(在match中将其定义为el并且{{},则正则表达式匹配功能需要存在捕获组。 1}}。

所以,我建议following solution

pPat(el)

然后,

rPat(el)

关于模式的一些注释:

  • val rPat="""\b(R\d{4})\b""".r.unanchored val pPat="""\b(P\.\d{2}\.\d{2}\.\d{2})\b""".r.unanchored val matcher= (s:String) => s match {case pPat(el)=> println(el) // print the P.25.01.25 case rPat(el)=>println(el) // print R0100 case _ => println("no match") } - 领先的单词边界
  • val pSt=" P.25.01.21 - Hello whats going on?" matcher(pSt) // => P.25.01.21 val pSt2_bad=" CP.2334565.01124.212 - Hello whats going on?" matcher(pSt2_bad) // => no match val rSt= "R0010 test test 3,870" matcher(rSt) // => R0010 val rSt2_bad = "CSR00105 test test 3,870" matcher(rSt2_bad) // => no match - 正好匹配4位数的捕获组
  • \b - 尾随字边界

由于用于定义字符串文字的三引号,因此无需转义反斜杠。

答案 1 :(得分:1)

在您的模式中引入群组:

val rPat=".*([R]{1}[0-9]{4}).*".r

val pPat=".*([P]{1}[.]{1}[0-9]{2}[.]{1}[0-9]{2}[.]{1}[0-9]{2}).*".r 

...

scala> matcher(pSt)
P.25.01.21

scala> matcher(rSt)
R0010

答案 2 :(得分:0)

如果以下列方式编写代码,将生成所需的结果。随后的参考API文档是http://www.scala-lang.org/api/2.12.1/scala/util/matching/Regex.html

  //should match R0010, R0100,R0300 etc
  val rPat="[R]{1}[0-9]{4}".r
  // should match P.25.01.21 , P.27.03.25 etc
  val pPat="[P]{1}[.]{1}[0-9]{2}[.]{1}[0-9]{2}[.]{1}[0-9]{2}".r


  def main(args: Array[String]) {
    val pSt=" P.25.01.21 - Hello whats going on?"
    val pPatMatches = pPat.findAllIn(pSt);
    pPatMatches.foreach(println)
    val rSt= "R0010  test test 3,870"
    val rPatMatches = rPat.findAllIn(rSt);
    rPatMatches.foreach(println)

  }

请告诉我这是否适合您。