我有网址http://faq.sipbroker.com/tiki-index.php?page=phone+numbers
,我需要从网址中提取文件扩展名(php
)。
我只能使用C ++和Boost。
我怎么能这样做?有一些例子,但有一些其他的像Poco等...但我只能使用Boost
答案 0 :(得分:2)
在这种情况下,该方案为http
。提取该方案非常容易,因为uri从方案开始,然后是冒号。
您正在寻找的是hierarchical part
的一部分。要扫描此部分以查找作为文件扩展名的子字符串,这是一项复杂的任务。如果您不想使用库,可能需要查看一个库(如cppnetlib uri)并复制现有uri解析器的一些代码。这真的不是小事。
cpp-netlib uri使用boost::spirit
作为解析器。您可以在uri_parser.cpp
编辑: 我想你想要提取你想要解释为文件扩展名的东西。如果您将“文件扩展名”定义为(可选)query part之前的最后一个点后面的字符,则可以采用简化方法。
查询组件由第一个问题指示 标记(“?”)字符并以数字符号(“#”)字符结束 或者在URI的末尾。
std::string::size_type FindNth(const std::string& str, char c, unsigned n){
std::string::size_type pos = 0;
for (unsigned i = 0; i < n; ++i)
pos = str.find(c, pos + 1);
return pos;
}
std::string FindExension(const std::string& uri) {
auto path = FindNth(uri, '/', 3);
if (path == std::string::npos)
return "";
auto query = uri.find('?', path);
auto dot = uri.rfind('.', query);
if (dot == std::string::npos || dot < path)
return "";
return uri.substr(dot, query - dot);
}
答案 1 :(得分:0)
编辑:这里所谓的scheme
,根据hansmaad的答案,实际上称为hierarchical part
。无论如何,我的答案的原则应该是明确的。
我会反过来这样做:定义所有可能的方案,然后编写一个使用std::string::find
来搜索其中一个方案的小函数:
#include<string>
#include<array>
#include<iostream>
std::string find_scheme(const std::string& url)
{
static std::array<std::string,2> scheme = {{"php", "whatever"}};
for(int i=0;i<scheme.size();++i)
{
if(url.find(scheme[i])!=std::string::npos)
{
return scheme[i];
}
}
return "scheme not found";
}
int main()
{
std::string your_url = "http://faq.sipbroker.com/tiki-index.php?page=phone+numbers";
std::cout<<find_scheme(your_url)<<std::endl;
}
这比从url-string中提取一些子字符串更安全,甚至不需要提升。
编辑:好的,“更安全”是相对的...我的意思比手写的例程更安全。然而,例如,http://www.php.com/tiki-index.asp
这样的ansatz失败了。在这种情况下,要么调整我的&lt;常规搜索第三个斜杠( - 或者其他),或者使用另一个答案中建议的库。