2009-04-07 18 views

Respuesta

2

Escriba un analizador personalizado o use una de las funciones de reemplazo de cadenas para reemplazar el separador ':' y luego use sscanf().

+15

Hay muchas trampas para ver, por lo que un analizador personalizado me parece una mala idea. – bortzmeyer

+0

@bortzmeye: eso no hace que la sugerencia sea inválida. Es un razonamiento vago. Además, un analizador personalizado es el más poderoso/eficiente/libre de dependencia. El sscanf es más fácil de equivocarse. – dirkgently

+4

¿cómo es "escribir un código que hace lo que necesita" una respuesta aceptada? – Spike0xff

9

Con un regular expression si quieres de la manera más fácil. De lo contrario, use FLEX/BISON.

También es posible usar un URI parsing library

+1

De hecho, usar una biblioteca parece ser lo único razonable, ya que hay muchas trampas (http vs. https, puerto explícito, codificación en la ruta, etc.). – bortzmeyer

+0

Hola, escribí un BNF para la URL, así. URL = "http: //" {IP} {PORT}? {PÁGINA}? Un flex generó un archivo que analizó la url. Pero cómo buscar las partes individuales como IP, PORT y PAGE. de la URL –

9

I writed un simple sscanf uso de códigos. Quiero tener una forma básica de analizarlo.

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

¿En qué plataforma está esto?No sabía que podrías poner regexp como [^:] en un formato sscanf. –

+0

Mi plataforma es: uname -a Linux ubuntu 2.6.24-21-generiC# 1 SMP Martes 21 de octubre 23:43:45 UTC 2008 i686 GNU/Linux –

+4

[^:] no es una expresión regular en este contexto, es meramente un especificador de formato especial para sscanf(). Es estándar. Ver, por ejemplo, esta página de manual: . – unwind

22

Personalmente, me roban el módulo HTParse.cfrom the W3C (se utiliza en el navegador Web lynx, por ejemplo). A continuación, puede hacer cosas como:

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

Lo importante acerca del uso de una biblioteca bien establecida y depurado es que no caigan en las típicas trampas de análisis de URL (muchas expresiones regulares fallan cuando el huésped es una Dirección IP, por ejemplo, especialmente una IPv6).

+1

En particular, tenga en cuenta que con IPv6 hay casos ambiguos si intenta utilizar el separador de dos puntos. p.ej. 3ffe: 0501 :: 1: 2, es un puerto de 2 o una dirección completa con su puerto predeterminado. Las especificaciones de URL han tratado esto, al igual que las bibliotecas preescritas. – bitmusher

+3

Tenga en cuenta que no existe una ambigüedad real. El estándar URI, RFC 3986, es claro y su ejemplo es ilegal (necesita corchetes). – bortzmeyer

+2

Gracias, esto es reconfortante. Tenía la impresión errónea de que el código del usuario, como las barras de direcciones del navegador, aceptaba las direcciones sin corchetes. Un recorrido rápido por algunos navegadores populares revela que este no es el caso. – bitmusher

2

Este tiene un tamaño reducido y funcionó excelente para mí http://draft.scyphus.co.jp/lang/c/url_parser.html. Solo dos archivos (* .c, * .h).
Tuve que adaptar el código [1].

[1] cambiar todas las llamadas de función de http_parsed_url_free (puntilla) para parsed_url_free (puntilla)

//Rename the function called 
    //http_parsed_url_free(purl); 
    parsed_url_free(purl); 
+2

@ tremendows: Excelente enlace. Funciona a las mil maravillas. –

+3

Lamentablemente, el excelente código está protegido por derechos de autor 'todos los derechos reservados', por lo que no debe utilizarse en un proyecto que no sea personal. –

+1

Excelente enlace. Funciona como un encanto –

0

Este C GIST podría ser útil. Implementa una solución C pura con sscanf.

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

Utiliza

// 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;} 
(...) 
+0

en tercer lugar si la declaración nunca se probará, porque el segundo tiene el mismo significado, por lo que podría causar un problema con el puerto/página – Risinek

9

Puede ser tarde, ... lo que he utilizado, es - la función http_parser_parse_url() y las macros necesarias separadas hacia fuera de Joyent/HTTP parser lib - que funcionaba bien, ~600 LOC.

+0

Sí. El analizador HTTP de node.js es excelente y está muy bien probado para cualquier cosa que tenga que ver con las solicitudes/respuestas HTTP. –

Cuestiones relacionadas