2009-04-07 78 views
29

我有這樣一個URL:使用C解析URL的最佳方法?

http://192.168.0.1:8080/servlet/rece 

我想解析URL得到的值:

IP: 192.168.0.1 
Port: 8080 
page: /servlet/rece 

我該怎麼辦呢?

+0

for windows,use CoInternetParseUrl – Jichao 2015-06-13 09:07:45

回答

2

編寫自定義分析器或使用其中一個字符串替換函數替換分隔符':',然後使用sscanf()

+15

有許多陷阱要觀看,所以自定義解析器在我看來似乎是一個壞主意。 – bortzmeyer 2009-04-07 16:53:29

+0

@bortzmeye:不會使建議無效。這是模糊的推理。另外,自定義分析器是最強大/有效/無依賴的。 sscanf更容易出錯。 – dirkgently 2009-04-07 17:00:05

+4

「如何編寫一些你需要的代碼」是一個被接受的答案? – Spike0xff 2016-08-21 03:47:06

9

regular expression如果你想要簡單的方法。否則使用FLEX/BISON

你也可以使用一個URI parsing library

+1

事實上,使用庫似乎是唯一合理的事情,因爲有很多陷阱(http與https,顯式端口,路徑中的編碼等)。 – bortzmeyer 2009-04-07 17:05:34

+0

嗨,我寫了一個BNF的url,像這樣。 URL =「http://」{IP} {PORT}? {頁}? flex生成一個解析url的文件。但是,如何獲取IP,PORT和PAGE等各個部分。從URL – 2016-07-07 06:58:17

9

我所著一個簡單的代碼使用sscanf的。我想有一個基本的方法來解析它。

cat urlparse.c 
#include <stdio.h> 

int main(void) 
{ 
    const char text[] = "http://192.168.0.2:8888/servlet/rece"; 
    char ip[100]; 
    int port = 80; 
    char page[100]; 
    sscanf(text, "http://%99[^:]:%99d/%99[^\n]", ip, &port, page); 
    printf("ip = \"%s\"\n", ip); 
    printf("port = \"%d\"\n", port); 
    printf("page = \"%s\"\n", page); 
    return 0; 
} 

./urlparse 
ip = "192.168.0.2" 
port = "8888" 
page = "servlet/rece" 
+0

這是什麼平臺?我不知道你可以把像[^:]這樣的正則表達式放在sscanf格式中。 – 2009-04-07 15:44:15

+0

我的平臺是:uname -a Linux ubuntu 2.6.24-21-generic#1 SMP Tue Oct 21 21:43:45 UTC 2008 i686 GNU/Linux – 2009-04-08 01:35:49

22

就個人而言,我偷HTParse.c模塊from the W3C(它在lynx Web瀏覽器中使用,例如)。然後,你可以做這樣的事情:

strncpy(hostname, HTParse(url, "", PARSE_HOST), size) 

有關使用以及建立和調試庫最重要的事情是,你不屬於URL的典型 陷阱解析(許多正則表達式失敗時,主機是IP地址,例如,特別是IPv6)。

2

這一個已經減小了尺寸,併爲我工作出色http://draft.scyphus.co.jp/lang/c/url_parser.html。只有兩個文件(* .c,* .h)。
我必須修改代碼[1]。

[1]改變所有功能從http_parsed_url_free調用(金銀絲)到parsed_url_free(金銀絲)

//Rename the function called 
    //http_parsed_url_free(purl); 
    parsed_url_free(purl); 
0

此C要旨可能是有用的。它使用sscanf實現純粹的C解決方案。

https://github.com/luismartingil/per.scripts/tree/master/c_parse_http_url

它採用

// Parsing the tmp_source char* 
if (sscanf(tmp_source, "http://%99[^:]:%i/%199[^\n]", ip, &port, page) == 3) { succ_parsing = 1;} 
else if (sscanf(tmp_source, "http://%99[^/]/%199[^\n]", ip, page) == 2) { succ_parsing = 1;} 
else if (sscanf(tmp_source, "http://%99[^:]:%i[^\n]", ip, &port) == 2) { succ_parsing = 1;} 
else if (sscanf(tmp_source, "http://%99[^\n]", ip) == 1) { succ_parsing = 1;} 
(...) 
9

可能會遲到,... 什麼我都用過,就是 - http_parser_parse_url()功能和Joyent/HTTP parser lib中分離出所需要的宏 - 運行良好, ~600 LOC。