2016-12-06 40 views
3

假設我有一個網址,如:從URL中提取領域斯卡拉-JS

https://example.com/myproject/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all 

,或者它可能是在本地主機上像一個網頁:

localhost:63342/my project/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all 

,我已經提取查詢字段從2-d陣列這些URL(後出現「?」)如下:

_ijt | hsdlgh8h5g8hh489sajoej 
a  | 102 
b  | a m 
c  | 45 
d  | all 
e  | all 

請大家注意,在「b」領域,我把它換成「%20」無線一個空間。這些字段如_ijt,a,b,c,d,e等可以在數量和名稱上有所不同,例如'a'可以是'城市'。 到目前爲止,我已經使用正則表達式來提取'?'後的部分然後使用split(「&」)方法將字符串拆分爲多個字符串。 碼 -

val url=localhost:63342/my project/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all 
val pattern="""(http|htpps)([A-Za-z0-9\:\/\%\-\.]*)\?""".r 
val temp_url=pattern.replaceFirstIn(url,"") 
val fields=temp_url.split("&") 
println(fields.foreach(println)) 

,輸出是:

_ijt=hsdlgh8h5g8hh489sajoej 
a=102 
b=a%20m 
c=45 
d=all 
e=all 

但它似乎並沒有被這樣做的正確方法。任何幫助?

回答

1

你需要調用js.URIUtils.decodeURIComponent上查詢參數值:

val fields=temp_url.split("&").map(js.URIUtils.decodeURIComponent) 

decodeURIComponentnative Javascript function,爲此scala.js有a simple interface

或者,您可以使用一些庫來解析用Scala編寫的URL。解析URL通常是安全隱患,很容易犯錯。圖書館通常還支持任何滿足相關標準/ RFC的輸入。

3

使用js.URIUtils.decodeURIComponent來準確解碼%編碼的字符。

+0

它解決了問題「一%20米」,但在URL的末尾想,我加上'#clinic'然後它會顯示'引擎=所有#clinic'這是不可取的。此外,我必須使用'fields.foreach(println)'來打印這些字段。但我想將每個字段存儲到一個單獨的變量中。我怎樣才能做到這一點? – Ishan

+2

使用'java.net.URI'來可靠地解析這樣的URL。它由Scala.js支持(雖然不是'java.net.URL')。 – sjrd

0

令人驚訝的是,很難找到一個適用於Scala.js和Scala(jvm)的整個庫。 java.net.URI將爲您提供查詢字符串,並且java.net.URLDecoder.decode將刪除URL編碼,但我沒有看到任何可以讓您獲得精美結構化查詢片段的內容。這不是火箭科學,但它很常見,你會認爲你不需要自己寫。

Fastparse將做的工作:

val url = new java.net.URI("http://example.com/?a=1&b%20=b+is+2&c=#someAnchor?a=b") 
    println(s"query string is: ${url.getQuery}") 

    val individualElements = 
    P(CharsWhile { 
     case '&' | '=' | '#' => false 
     case _ => true 
    }.!.map(x => java.net.URLDecoder.decode(x, "UTF-8"))) 

    val keyValuePair: core.Parser[(String, Option[String]), Char, String] = 
    individualElements ~ "=" ~ individualElements.? 

    val pairs: core.Parser[Seq[(String, Option[String])], Char, String] = 
    keyValuePair.rep(sep = "&") 

    val parsed: Parsed[Seq[(String, Option[String])], Char, String] = 
    pairs.parse(url.getQuery) 

    parsed match { 
    case Success(items, _) => println(s"items: ${items.toList}") 
    // prints: 
    // items: List((a,Some(1)), (b ,Some(b is 2)), (c,None)) 
    } 
0

大廈建議使用「decodeURIComponent」和「java.net.URI中的」我想出了這個快速和骯髒的解決方案,幾乎肯定可以改進,但也許它可以幫助:

def getUrlParameters(url: String): Map[String, Array[String]] = { 
    java.net.URI.create(url).getQuery.split('&').map(js.URIUtils.decodeURIComponent).map { p => 
     val split = p.split('=') 
     (split.head, split.tail.mkString("=")) 
    }.groupBy(_._1).map(m => m._1 -> m._2.map(_._2)) 
} 

def getUrlParameter(url: String, parameter: String): Option[String] = { 
    getUrlParameters(url).get(parameter).flatMap(_.headOption) 
}