Простой способ проанализировать URL в кросс-платформенном C++?

generate_series() возвращает набор строк , который похож на таблицу. И, очевидно, вы не можете привести набор к одному типу данных. Ваше приведение похоже на select * from cast(some_table as date)

Вам необходимо привести значение, возвращаемое функцией:

select gs.date::date as "date"
from generate_series(current_date - interval '7 days', current_date, '1 day') gs(date)

67
задан Elliot Cameron 13 July 2012 в 19:06
поделиться

10 ответов

Существует библиотека, которая предлагается для включения Boost и позволяет легко анализировать URI HTTP. Он использует Boost.Spirit и также распространяется под лицензией Boost Software License. Это библиотека cpp-netlib, документацию по которой вы можете найти на http://cpp-netlib.github.com/ - вы можете скачать последнюю версию с http: // github. com / cpp-netlib / cpp-netlib / downloads .

Соответствующий тип, который вы захотите использовать, - это boost :: network :: http :: uri , и он описан здесь .

28
ответ дан 24 November 2019 в 14:39
поделиться

Я разработал «объектно-ориентированное» решение, один класс C ++, который работает с одним регулярным выражением, таким как решения @ Mr.Jones и @velcrow. Мой Url класс выполняет разбор url / uri.

Мне кажется, я улучшил регулярное выражение velcrow , чтобы сделать его более устойчивым и включил также часть имени пользователя.

Следуя первой версии моей идеи, я выпустил тот же код, улучшенный, в моем GPL3 лицензированном проекте с открытым исходным кодом Cpp URL Parser .

Пропущенная #ifdef/ndef часть раздувания, следующая за Url.h

#include <string>
#include <iostream>
#include <boost/regex.hpp>

using namespace std;

class Url {
public:
    boost::regex ex;
    string rawUrl;

    string username;
    string protocol;
    string domain;
    string port;
    string path;
    string query;
    string fragment;

    Url();

    Url(string &rawUrl);

    Url &update(string &rawUrl);
};

Это код файла реализации Url.cpp:

#include "Url.h"

Url::Url() {
    this -> ex = boost::regex("(ssh|sftp|ftp|smb|http|https):\\/\\/(?:([^@ ]*)@)?([^:?# ]+)(?::(\\d+))?([^?# ]*)(?:\\?([^# ]*))?(?:#([^ ]*))?");
}

Url::Url(string &rawUrl) : Url() {
    this->rawUrl = rawUrl;
    this->update(this->rawUrl);
}

Url &Url::update(string &rawUrl) {
    this->rawUrl = rawUrl;
    boost::cmatch what;
    if (regex_match(rawUrl.c_str(), what, ex)) {
        this -> protocol = string(what[1].first, what[1].second);
        this -> username = string(what[2].first, what[2].second);
        this -> domain = string(what[3].first, what[3].second);
        this -> port = string(what[4].first, what[4].second);
        this -> path = string(what[5].first, what[5].second);
        this -> query = string(what[6].first, what[6].second);
        this -> fragment = string(what[7].first, what[7].second);
    }
    return *this;
}

Пример использования:

string urlString = "http://gino@ciao.it:67/ciao?roba=ciao#34";
Url *url = new Url(urlString);
std::cout << " username: " << url->username << " URL domain: " << url->domain;
std::cout << " port: " << url->port << " protocol: " << url->protocol;

Вы также можете обновить объект Url, чтобы представлять (и анализировать) другой URL:

url.update("http://gino@nuovociao.it:68/nuovociao?roba=ciaoooo#")

Я сейчас изучаю C ++, поэтому я не уверен, что следовал 100% лучших практик C ++. Любой отзыв приветствуется.

P.s: давайте посмотрим на Cpp URL Parser , там есть уточнения.

Веселись

0
ответ дан Fabiano Tarlao 24 November 2019 в 14:39
поделиться

Небольшая зависимость, которую вы можете использовать, это uriparser , которая недавно перешла на GitHub.

Вы можете найти минимальный пример в их коде: https://github.com/uriparser/uriparser/blob/63384be4fb8197264c55ff53a135110ecd5bd8c4/tool/uriparse.c

Это будет более легким, чем Boost или Poco. Единственный улов в том, что это C.

Существует также пакет Buckaroo :

buckaroo add github.com/buckaroo-pm/uriparser
2
ответ дан sdgfsdh 24 November 2019 в 14:39
поделиться

Вы можете попробовать библиотеку с открытым исходным кодом C ++ REST SDK (созданную Microsoft, распространяемую под лицензией Apache License 2.0). Он может быть построен для нескольких платформ, включая Windows, Linux, OSX, iOS, Android). Существует класс под названием web::uri, в который вы помещаете строку и можете получать отдельные компоненты URL. Вот пример кода (протестирован в Windows):

#include <cpprest/base_uri.h>
#include <iostream>
#include <ostream>

web::uri sample_uri( L"http://dummyuser@localhost:7777/dummypath?dummyquery#dummyfragment" );
std::wcout << L"scheme: "   << sample_uri.scheme()     << std::endl;
std::wcout << L"user: "     << sample_uri.user_info()  << std::endl;
std::wcout << L"host: "     << sample_uri.host()       << std::endl;
std::wcout << L"port: "     << sample_uri.port()       << std::endl;
std::wcout << L"path: "     << sample_uri.path()       << std::endl;
std::wcout << L"query: "    << sample_uri.query()      << std::endl;
std::wcout << L"fragment: " << sample_uri.fragment()   << std::endl;

Вывод будет:

scheme: http
user: dummyuser
host: localhost
port: 7777
path: /dummypath
query: dummyquery
fragment: dummyfragment

Существуют и другие простые в использовании методы, например, чтобы получить доступ к отдельным парам атрибут / значение из запроса, разбить путь на компоненты и т. д.

1
ответ дан Vivit 24 November 2019 в 14:39
поделиться

QT имеет QUrl для этого. У GNOME есть SoupURI в libsoup , который вы, вероятно, найдете немного более легким.

1
ответ дан Matthew Flaschen 24 November 2019 в 14:39
поделиться

Эта библиотека очень маленькая и легкая: https://github.com/corporateshark/LUrlParser

Однако, это только синтаксический анализ, без нормализации / проверки URL.

2
ответ дан Sergey K. 24 November 2019 в 14:39
поделиться

В библиотеке Poco теперь есть класс для анализа URI и обратной связи хоста, сегментов пути, строки запроса и т. Д.

https://pocoproject.org/pro/docs/Poco.URI.html

5
ответ дан yan 24 November 2019 в 14:39
поделиться

Класс URI POCO может анализировать URL-адреса для вас. Следующий пример является сокращенной версией из слайдов URI и UUID POCO :

#include "Poco/URI.h"
#include <iostream>

int main(int argc, char** argv)
{
    Poco::URI uri1("http://www.appinf.com:88/sample?example-query#frag");

    std::string scheme(uri1.getScheme()); // "http"
    std::string auth(uri1.getAuthority()); // "www.appinf.com:88"
    std::string host(uri1.getHost()); // "www.appinf.com"
    unsigned short port = uri1.getPort(); // 88
    std::string path(uri1.getPath()); // "/sample"
    std::string query(uri1.getQuery()); // "example-query"
    std::string frag(uri1.getFragment()); // "frag"
    std::string pathEtc(uri1.getPathEtc()); // "/sample?example-query#frag"

    return 0;
}
8
ответ дан Michael Mc Donnell 24 November 2019 в 14:39
поделиться

Также может представлять интерес http://code.google.com/p/uri-grammar/ , который, как и netlib Дина Майкла, использует метод повышения для анализа URI. Наткнулся на это в Пример простого парсера выражений с использованием Boost :: Spirit?

2
ответ дан Community 24 November 2019 в 14:39
поделиться

Ужасно извиняюсь, не смог удержаться. :s

url.hh

#ifndef URL_HH_
#define URL_HH_    
#include <string>
struct url {
    url(const std::string& url_s); // omitted copy, ==, accessors, ...
private:
    void parse(const std::string& url_s);
private:
    std::string protocol_, host_, path_, query_;
};
#endif /* URL_HH_ */

url.cc

#include "url.hh"
#include <string>
#include <algorithm>
#include <cctype>
#include <functional>
using namespace std;

// ctors, copy, equality, ...

void url::parse(const string& url_s)
{
    const string prot_end("://");
    string::const_iterator prot_i = search(url_s.begin(), url_s.end(),
                                           prot_end.begin(), prot_end.end());
    protocol_.reserve(distance(url_s.begin(), prot_i));
    transform(url_s.begin(), prot_i,
              back_inserter(protocol_),
              ptr_fun<int,int>(tolower)); // protocol is icase
    if( prot_i == url_s.end() )
        return;
    advance(prot_i, prot_end.length());
    string::const_iterator path_i = find(prot_i, url_s.end(), '/');
    host_.reserve(distance(prot_i, path_i));
    transform(prot_i, path_i,
              back_inserter(host_),
              ptr_fun<int,int>(tolower)); // host is icase
    string::const_iterator query_i = find(path_i, url_s.end(), '?');
    path_.assign(path_i, query_i);
    if( query_i != url_s.end() )
        ++query_i;
    query_.assign(query_i, url_s.end());
}

main.cc

// ...
    url u("HTTP://stackoverflow.com/questions/2616011/parse-a.py?url=1");
    cout << u.protocol() << '\t' << u.host() << ...
21
ответ дан 24 November 2019 в 14:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: