2016-12-06 3 views
3

が、私はのようなURLをしたとします抽出フィールド

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 

と私は抽出するためにきましたクエリフィールド(後に現れる「?」)これらのURLから2次元配列で、次のよう:

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

「B」フィールドに、私は「%20」のwiを交換してきたことに注意してくださいスペース。 _ijt、a、b、c、d、eなどのフィールドは、番号や名前が異なる場合があります。たとえば、 'a'は 'city'とすることができます。 これまでのところ、正規表現を使って '?'の後の部分を抽出しました。 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) 

decodeURIComponentはscala.jsがa simple interfaceを持っているnative Javascript function、です。

また、Scalaで書かれたURLを解析するためにライブラリを使用することもできます。 URLの解析はセキュリティ上の問題となることが多く、間違いを犯すのは簡単です。ライブラリは、通常、関連するStandards/RFCを満たす入力をサポートします。

3

js.URIUtils.decodeURIComponentを使用して、%エンコード文字を正確にデコードします。

+0

が、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を」私はほぼ確実に改善することができ、この間に合わせの解決策を考え出したが、多分それは役立ちます。それは「%の20メートル」で問題を解決し

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) 
} 
関連する問題