2011-05-21 109 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; 
}