读书人

超难算法:取得URL中如bbs.csdn.net的

发布时间: 2012-04-08 14:38:30 作者: rapoo

超难算法:取得URL中如bbs.csdn.net的部分
例如:
一个地址:http://user:pass@www.163.com:8080/music/chs/index.aspx?mid=23081712

可以先删除http://user:pass@,然后从:8080/开始把后面的也删除了,这就得到www.163.com,如果我表达的不清楚下面有程序描述,


Delphi(Pascal) code
function GetDomainRoot(url: string): string;//获得一个URL地址的域var p1:integer;begin     //http://user:pass@www.163.com:8080/music/chs/index.aspx?mid=23081712     //    p1     result:='';     if LeastUrlRequest(url) then//检验URL是否合法,判断是否含有,{<>这一类的字符     begin        //去掉协议        p1:=pos('://',url);        if (p1>0) then           Delete(url,1,p1+2);        p1:=pos('/',url);        if (p1>1) then        begin           //得到主机地址user:pass@www.163.com:8080           url:=Copy(url,1,p1-1);           if url<>'' then           begin              //去掉用户名和密码www.163.com:8080              p1:=pos('@',url);              if (p1>0) then                 Delete(url,1,p1);              //去掉端口www.163.com              Delete(url,pos(':',url),Length(url));           end;           if (pos('192.168.',url)>0)  or (NCpos('localhost',url)>0) or (Pos('.',url)<=0) then//局域网的不要              result:=''           else              result:=url;        end else if (length(url)>=3) and (url[1]<>'/') then //a.b满足域名或文件名的形式            result:=url;     end;end;


我能想到的最好的就是上面这个算法了,有没有更好的办法呢?还可以如何改进?

[解决办法]
好像这个是比较快的了
[解决办法]
@之前的删除掉
然后取:之前的字符
楼主的方法可以了
[解决办法]
正则表达式:(www.\w+.\w+)
[解决办法]
做网关还是代理的过滤啊? 100万次又不是要求在几秒内完成,分到一天里太闲了。。
[解决办法]
正则表达式要少好多代码
[解决办法]
楼主正解 用BASM 嵌到程序里去看看,
[解决办法]
很简单的字符串提取罢了,地址也就这么点字符,性能能差到哪去?
如果是这个地址不是死的,有可能是SINA,有可能是搜狐,但是结构是WWW.XXX.COM,那可以直接用POS函数来确定
没有必要去把其他的字符去掉和
VAR
STR1,STR2,STR3:STRING;
A,B,C:INTEGER;
BEGIN
STR1:='http://user:pass@www.163.com:8080/music/chs/index.aspx?mid=23081712';
STR2:='';//把地址设置为关键字;比如www.sina.com,如果是地址比较复杂的.就设关键字www.
STR3:='HTTP://';
if pos(str2,str1)>0 and pos(STR3,STR1)<>0 then

STR1:=STR2;//如果地址多个,就用正则表达式,咋写的不记得了.取WWW.和.XXX之间的


END;

我觉得力图程序短小才是重要的,多用逻辑结构少用函数.太复杂的函数运行起来肯定不太好吧.
[解决办法]
简单呢,就是取得URL中的域名或IP。
1. 查找 //, 删除它及其左边的部分
2. 查找 /, 删除它及其右边的部分
3. 查找 @, 如果找到,删除它及其左边的部分
4. 查找 :, 如果找到,删除它及其右边的部分
[解决办法]
楼主的程序Pos,Copy和Delete已使用多次,这样的代码效率高不到哪儿去,切记!少用字符串相加,拷贝等函数。

其实取 URL 中的 Host 部分是非常容易的事,一次扫描就搞定!使用状态机来处理。
[解决办法]
建议用标准函数完成,对可靠性有要求就别用控件的
即使用COPY,POS之类的对于不是要求极高的话,仍旧足够的
每天几百万次?肯定够了
[解决办法]
COPY,POS之类函数应该也是通过地址(或指针)操作来实现,多次使用可能意味着多次重复遍历该url string。
针对楼主给出的url字符串形式,只要找到(/,:,@)这类字符就可以提取出结果。
因此考虑使用字符指针一次遍历的方法,程序如下:
function GetDomainRoot(url: string): string;
//获得一个URL地址的域
var i:integer;//url下标
pstr:pchar;
flag:boolean;//判断标志
begin
//http://user:pass@www.163.com:8080/music/chs/index.aspx?mid=23081712


i := 1;
flag := false;
pstr := @url;
// result:='';
if LeastUrlRequest(url) then//检验URL是否合法,判断是否含有,{}<>这一类的字符
//我在Delphi7里没找到这个函数,此处应该也是遍历url查找,可以将它整合到下面的判断中
begin
while url[i] <>'' do
//此处用for可能能更好的替代处理if (length(url)>=3) and (url[1]<>'/') then
//我有些看不懂上句的具体作用,^_^
//url[i] <>'' 可以 替代为 ord(url[i])<> 0 ,我不太清楚哪个好
begin
if url[i] = '.' then
flag := True //找到 . 意味着已经进入域名,那么域名头不用再定位
else
begin
if (url[i] = '/') or (url[i] = '@') or (url[i] = ':') then
begin
if flag = false then
pstr := @url[i+1] //不断的定位域名头
else
begin
url[i] := char(0); //将url后面多于的部分删除
break;
end;
end;
end;
i := i+1; //inc(i);
end;
result := pstr;
if (pos('192.168.',result)>0) then //局域网的不要 ,(Pos('.',url)<=0) then已经在while里实现了
result:='';
end
else
result := '';
end;

[解决办法]
url[i] 的操作已经多了一次间接寻址,建议直接使用 pCh = Pointer(url); pCh^ 取字符,下一个字符使用 Inc(pCh) 即可。

读书人网 >.NET

热点推荐