在Scala中针对带有问号的URL进行模式匹配

时间:2018-11-02 13:29:42

标签: scala

我正在尝试从包含问号的URL中提取一些值。

但是,以下代码不起作用。您能帮助我找出问题出在哪里吗?

val LibraryPattern = ".*/library/([A-Za-z0-9\\-]+)?book=([A-Za-z0-9\\-]+)".r
val url = "https://bookscollection.com/library/mylib?book=abc"
  Try(new URL(url)) match {
    case Success(url) =>
      println("my url:"+url)
      url.getPath match {
        case LibraryPattern(libId, bookId) =>

          println(libId)
          println(bookId)
        case _ =>
      }
  }

3 个答案:

答案 0 :(得分:2)

? is a special character in Regex(实际上使前一个字符/组为可选)。您需要对其进行转义。

编辑url.getPath仅返回/library/mylib,因此,如果您希望正则表达式匹配,则不要使用它。

val LibraryPattern = ".*/library/([A-Za-z0-9\\-]+)\\?book=([A-Za-z0-9\\-]+)".r
val url = "https://bookscollection.com/library/mylib?book=abc"
Try(new URL(url)) match {
  case Success(url) =>
    println("my url:"+url)
    url.toString match {
      case LibraryPattern(libId, bookId) =>
        println(libId)
        println(bookId)
      case _ =>
    }
}

答案 1 :(得分:2)

URL对象已经为您解析了URL。 getPath返回?之前的所有内容,使用getQuery获取?之后的部分:

 val LibraryPattern = ".*/library/([A-Za-z0-9\\-]+)".r
 val BookPattern = "book=([A-Za-z0-9\\-]+)".r
 val url = "https://bookscollection.com/library/mylib?book=abc"
 Try(new URL(url)) match {
   case Success(url) =>
     url.getPath match {
       case LibraryPattern(libId) =>
         url.getQuery match {
           case BookPattern(bookId) =>
             println(libId)
             println(bookId)
         }
     }
 }

答案 2 :(得分:2)

由于几乎没有答案指出了如何修复代码示例,因此我想提出另一种解决方案。就将来的可读性,类型安全性和代码库的灵活性而言,使用正则表达式解析URL可能效率不高。

我想建议使用scala-uri library或类似的东西。

有了这个库,人们就可以简单地进行URL解析:

import io.lemonlabs.uri.Url 

val url = Url.parse("https://bookscollection.com/library/mylib?book=abc") 
val lastPathPart = url.path.parts.last 
// println(lastPathPart)
// res: String = "mylib"
val bookParam: Option[String] = url.query.param("book")
// println(bookParam)
// res: Option[String] = Some("abc")