2017-04-24 86 views
3

我想提取匹配丝束正则表达式模式我定义的一个字符串的一部分:模式匹配提取字符串的Scala

//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 

我不知道,如果正则表达式是错误的,但比赛方法作品在元素上。那么这种方法有什么问题呢?

回答

2

当您使用模式与字符串匹配,你需要牢记的是:

  • 传递需要将整场比赛的.r模式字符串,否则,不会返回任何匹配(解决方法是制作图案)
  • 将其设为非锚定后,请注意不需要的匹配:R[0-9]{4}将匹配CSR123456R1234(解决方案是根据您的实际需求是什么,通常是字边界不够,或负可用于\blookarounds不同)
  • 里面一个match块,正则表达式匹配功能需要捕获组是如果您想获得一些价值(如您在pPat(el)rPat(el)中将其定义为el)。

所以,我建议following solution

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 

的一些注意事项上的图案:

  • \b - 领先字边界
  • (R\d{4}) - 捕获组匹配是4位数
  • \b - 尾随字边界

由于用来定义字符串文字的三重引号,没有必要为了躲避反斜杠。

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 
+0

谢谢你的工作! –

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) 

    } 

请让我知道是否适合你。