2011-05-21 126 views
13

我正在閱讀歷史記錄,我希望當我遇到谷歌查詢時,我可以提取查詢字符串。我不使用請求或httputility,因爲我只是解析一個字符串。然而,當我遇到像這樣的網址,我的程序不能正確解析它:從URL字符串中提取查詢字符串

http://www.google.com.mt/search?client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&channel=s&hl=mt&source=hp&biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google

我試圖做的就是q的指數=和&指標,並採取詞語之間,但在這種情況下,&的索引將小於q =,它會給我錯誤。

有什麼建議嗎?

感謝您的回答,一切看起來不錯:) p.s.我無法使用httputility,不是我不想。當我添加一個對system.web的引用時,不包括httputility!它只包含在一個asp.net應用程序中。再次感謝

+0

因此,尋找與它爲q後立即..... – 2011-05-21 15:26:48

+0

要包括'HttpUtility',你只需要在項目中添加一個對'System.Web'程序集的引用。它不一定是一個asp.net應用程序。 – 2011-05-21 16:23:31

回答

21

爲什麼你不希望使用HttpUtility目前尚不清楚。你總是可以添加一個參考System.Web並使用它:

var parsedQuery = HttpUtility.ParseQueryString(input); 
Console.WriteLine(parsedQuery["q"]); 

如果這不是一個選項,然後也許這種做法將有助於:

var query = input.Split('&') 
       .Single(s => s.StartsWith("q=")) 
       .Substring(2); 
Console.WriteLine(query); 

它分割上&並尋找一個分割結果以"q="開頭,並將位置2的子字符串返回=後面的所有符號。假設是會有單個匹配,這對於這種情況似乎是合理的,否則將拋出異常。如果情況並非如此,則用Where替換Single,循環結果並在循環中執行相同的子字符串操作。

編輯:覆蓋在評論中提到的情況下此更新版本可用於:

int index = input.IndexOf('?'); 
var query = input.Substring(index + 1) 
       .Split('&') 
       .SingleOrDefault(s => s.StartsWith("q=")); 

if (query != null) 
    Console.WriteLine(query.Substring(2)); 
+0

當路徑部分中包含'&'時,這也會失敗。例如,http://example.com/ugly&but&legal&url&q=1234?q = 5678'。 – 2011-05-21 16:19:41

+0

@Jim更新。感謝您的反饋。 – 2011-05-21 18:26:49

6

如果您不想使用System.Web.HttpUtility(因此可以使用客戶端配置文件),您仍然可以使用Mono HttpUtility.cs,它只是一個獨立的.cs文件,可以嵌入到您的應用程序中。然後,您可以簡單地在類中使用ParseQueryString方法來正確解析查詢字符串。

2

如果你真的需要做的分析自己,只有感興趣的「Q」值那麼下面將工作:

 string url = @"http://www.google.com.mt/search?" + 
      "client=firefoxa&rls=org.mozilla%3Aen-" + 
      "US%3Aofficial&channel=s&hl=mt&source=hp&" + 
      "biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google"; 

     int question = url.IndexOf("?"); 
     if(question>-1) 
     { 
      int qindex = url.IndexOf("q=", question); 
      if (qindex > -1) 
      { 
       int ampersand = url.IndexOf('&', qindex); 
       string token = null; 

       if (ampersand > -1) 
        token = url.Substring(qindex+2, ampersand - qindex - 2); 
       else 
        token = url.Substring(qindex+2); 

       Console.WriteLine(token); 
      } 
     } 

但不要嘗試看看使用正確的URL語法分析器,它將爲您節省很多麻煩。

(修正了這個問題到底包含了「?」令牌的檢查,並支持在查詢字符串的結尾「Q」值(不帶「&」))

+0

當q「q =」或url的路徑部分包含&符時,這會失敗。像這樣:http://www.example.com/testo/thisq=99&xyzzy/hello?q=99。是的,這是合法的。您首先必須找到查詢字符串指示符('?'),並根據其他所有信息進行基礎。 – 2011-05-21 15:52:45

+0

非常真實!我會修改答案。 – 2011-05-21 15:59:19

3

爲什麼不你創建一個代碼,它返回從q=開始的字符串,直到下一個&

例如:

字符串s = historyString.Substring(url.IndexOf( 「Q =」));

int newIndex = s.IndexOf(「&」);

string newString = s.Substring(0,newIndex);

乾杯

+1

然後當用'http://www.example.com/testo/thisq=99&xyzzy/hello?q = 99'呈現失敗時 – 2011-05-21 15:54:15

2

使用可用的工具:

String UrlStr = "http://www.google.com.mt/search?client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&channel=s&hl=mt&source=hp&biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google"; 

NameValueCollection Items = HttpUtility.ParseQueryString(UrlStr); 

String QValue = Items["q"]; 
1

HttpUtility是罰款爲.NET Framework 。但是,該類不適用於WinRT應用程序。如果您想從Windows應用商店應用中的網址獲取參數,則需要使用WwwFromUrlDecoder。你可以用這個類創建一個對象,使用你想要從中獲取參數的查詢字符串,該對象有一個枚舉器並且還支持lambda表達式。

下面是一個例子

var stringUrl = "http://localhost/?name=Jonathan&lastName=Morales"; 
var decoder = new WwwFormUrlDecoder(stringUrl); 
//Using GetFirstByName method 
string nameValue = decoder.GetFirstByName("name"); 
//nameValue has "Jonathan" 

//Using Lambda Expressions 
var parameter = decoder.FirstOrDefault(p => p.Name.Contains("last")); //IWwwFormUrlDecoderEntry variable type 
string parameterName = parameter.Name; //lastName 
string parameterValue = parameter.Value; //Morales 

您還可以看到http://www.dzhang.com/blog/2012/08/21/parsing-uri-query-strings-in-windows-8-metro-style-apps

4

這裏是解決方案 -

string GetQueryString(string url, string key) 
{ 
    string query_string = string.Empty; 

    var uri = new Uri(url); 
    var newQueryString = HttpUtility.ParseQueryString(uri.Query); 
    query_string = newQueryString[key].ToString(); 

    return query_string; 
}