日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

一种精确从文本中提取URL的思路及实现

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一种精确从文本中提取URL的思路及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? 在今年三四月份,我接受了一個需求:從文本中提取URL。這樣的需求,可能算是非常小眾的需求了。大概只有QQ、飛信、阿里旺旺等之類的即時通訊軟件存在這樣的需求。在研究這個之前,我測試了這些軟件這塊功能,發現它們這塊的功能還是非常弱的。這類軟件往往也是惡意URL傳播的媒介,如果不能準確識別出URL,相應的URL安全檢測也無從談起。而且網上也有很多使用正則表達式的方法,可是我看了下,方法簡單但是不夠精確,對于要求不高的情況可以勝任,但是如果“壞人”想繞過這種提取也是很方便的。(轉載請指明出處)下面也是我在公司內部做的一次分享的內容:

URL介紹

全稱:Uniform Resource Locators。

最常見“最”標準的URL

? ? ? ? 例子:http://www.g.cn/

? ? ? ??衍生出瀏覽器可以接受的URL(在地址欄輸入的URL首先會被瀏覽器截獲,瀏覽器可更具其對URL的理解進行相關容錯)

? ? ? ? 協議后對斜杠無要求:

http:www.g.cn
http:\www.g.cn
http:\\/\www.g.cn

? ? ? ? 目前主流IM對最常見“最”標準的URL的識別沒有問題,但是對衍生出來的URL都是無法正確識別的。

比較常見但是“不標準”(無協議頭)URL

? ? 無協議頭,無二級域名

? ? ? ? 例子:g.cn

? ? 無協議頭,有二級域名www

? ? ? ? 例子:www.g.cn

? ? 無協議頭,有二級域名,但是不是www

? ? ? ? 例子:mp3.g.cn

? ? ? ??目前國內主流IM對URL的判別上,在沒有協議頭(http://等)時,尋找有沒有“www.”,如果存在“www.”,則認為其后是URL。

比較少見的URL

? ? 格式省略或者特殊的UR

  • 頂級域名后包含“點”
    • 例子:www.g.cn.(同www.g.cn)

? ? 部分省略

  • 例子:www.g.cn.?wd=3(同www.g.cn./?wd=3、www.g.cn/?wd=3)

包含用戶名和密碼的URL

  • 密碼不為空
    • 例子:username:password@www.g.cn
  • 密碼為空
    • 例子:username:@www.g.cn

? ? ? ??目前國內主流IM對這類URL判斷是不準確的,如上例只能識別為www.g.cn

比較特殊的URL

? ? 完全沒有分隔符的

? ? ? ? 例子:g.cnclick this(可以識別為g.cn,但是國內IM都不會去這么識別)

? ? 比較難以歸類的

? ? ? ? 例子:mailto:@g.cn(以mailto協議標準,這個URL不符合RFC規定,因為mailto:后面@之前應該有“用戶名”;以http或者ftp協議標準,這個URL是合法的,因為這個URL中用戶名位mailto,密碼為空。囧啊!)

? ? ? ??看一下國內一些IM的表現:

URL標準定義

? ? ? ??定義于RFC1738,詳細請見http://tools.ietf.org/html/rfc1738

? ? 具有相似的格式(ftp,http,https,wais,nntp……)

<scheme> ://<user>:<password>@<host>:<port>/<url-path>

? ? ? ??“<user>:<password>@”, “:<password>”,“:<port>”,和“/<url-path>” 是可選的。

? ? ? ??“<user>:<password>@”可以是“<user>@”(不需要密碼),也可以是“<user>:@”(密碼為空)。

? ? 形式多樣的(mailto,news)

? ? ? ? 形式太多樣,定義寬松

? ? 一些其他特殊協議(afs……)

? ? ? ??要么不用了,要么這份RFC沒給出定義,要么很少用。

格式相似的協議的URL Scheme的BNF范式

? ? HTTP(用來指定互聯網資源)

http://<host>:<port>/<path>?<searchpart>

? ? gopher (用來指定互聯網資源,已經很少用了)

gopher://<host>:<port>/<gopher-path>

? ? nntp(網絡新聞傳輸協議)

nntp://<host>:<port>/<newsgroup-name>/<article-number>

? ? telnet(Internet遠程登陸服務的標準協議和主要方式)

telnet://<user>:<password>@<host>:<port>/

? ? wais(廣域信息查詢系統)

wais://<host>:<port>/<database> 
wais://<host>:<port>/<database>?<search> 
wais://<host>:<port>/<database>/<wtype>/<wpath>

格式相似的協議的URL Scheme的BNF范式

? ? file(描述文件資源)

file://<host>/<path>

? ? prospero(Be used to designate resources that are accessed via the Prospero Directory Servic)

prospero://<host>:<port>/<hsoname>;<field>=<value>

形式多樣的協議的URL Scheme的BNF范式

? ? news

news:<newsgroup-name>.
news:<message-id>

? ? ? ? 例子:news:msnews.microsoft.com

? ? mailto

mailto:<rfc822-addr-spec>

? ? ? ? 例子:mailto:1@g.cn

一些其他特殊協議

afsAndrew File System global file names.
midMessage identifiers for electronic mail.
cidContent identifiers for MIME body parts.
nfsNetwork File System (NFS) file names.
tn3270Interactive 3270 emulation sessions.
mailserverAccess to data available from mail servers.
z39.50Access to ANSI Z39.50 services.

URL的RFC文檔對提取URL的幫助

  • 提供了所有的協議頭,幫助準確找到URL起始位置
  • 提供了http、ftp等協議名
  • 定義了各種URL的范式,為準確得提取URL有很大的幫助
    • 如ali-inc.com中的ali-inc部分要求“-”是可選的,且在存在“-”時,要求其左右存在數字或者字母。
    • 如user name和password部分(username:password@g.cn)如果出現“:”、 “@”或“/”時要加密,這將幫助尋找到URL的起始位置(@user:pass@g.cn提取的URL是user:pass@g.cn)。

? ? ? ? 基于以上問題,可以有種折中方案:將URL范式和現在已知的toplabel結合,構成一個新的范式。以下是RFC文檔中BNF范式結合實際問題被修改成的正則表達式:

((((ftp:|https:|http:)([\Q/\\E])*)|())(((%[0-9a-fA-F][0-9a-fA-F])|([a-zA-Z0-9])|([\Q$-_.+!*'(),;?&=\E]))+(:((%[0-9a-fA-F][0-9a-fA-F])|([a-zA-Z0-9])|([\Q$-_.+!*'(),;?&=\E]))*)?@)?(((((([a-zA-Z0-9]){1}([a-zA-Z0-9\-])*([a-zA-Z0-9]{1}))|([a-zA-Z0-9]))\.)+(biz|com|edu|gov|info|int|mil|name|net|org|pro|aero|cat|coop|jobs|museum|travel|arpa|root|mobi|post|tel|asia|geo|kid|mail|sco|web|xxx|nato|example|invalid|test|bitnet|csnet|onion|uucp|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw))|([0-9]{1,3}(\.[0-9]{1,3}){3}))(\:([0-9]+))?(([\Q/\\E])+((((%[0-9a-fA-F][0-9a-fA-F])|([a-zA-Z0-9])|([\Q$-_.+\!*'(),;:@&=\E]))*)(([\Q/\\E])*((%[0-9a-fA-F]{2})|([a-zA-Z0-9])|([\Q$-_.+\!*'(),;:@&=\E]))*)*)(\?((%[0-9a-fA-F]{2})|([a-zA-Z0-9])|([\Q$-_.+!*'(),;:@&=<>#"{}[] ^`~|\/\E]))*)*)*)

? ? ? ? 看著是不是特別復雜?是的!這將導致效率非常低下。(這是很久前一個做實驗的版本,不能保證其準確性)利用這個正則表達式中我們可以發現很多域名,這些域名都是我從某款安全輔助軟件的二進制文件中扒下來了。可能有人會認為這個正則效率的瓶頸在匹配這些域名上,其實不是,我做個實驗,主要的瓶頸在domainlabel(就是.com等之前的那部分)上,所以優化比較困難。而且這個正則還沒考慮一些特殊問題,比如將“。”識別成"."。

域名

biz|com|edu|gov|info|int|mil|name|net|org|pro|aero|cat|coop|jobs|museum|travel|arpa|root|mobi|post|tel|asia|geo|kid|mail|sco|web|xxx|nato|example|invalid|test|bitnet|csnet|onion|uucp|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw

? ? ? ? 這個域名還是比較全的,我沒有全部測試,只是大致看了下,畢竟是別人總結的,不知道別人是否在里面放了“標記”信息。我曾經擔心過xxx這個域名,還搜了下,發現很大!。還有請仔細看,這些域名中沒有數字,這為我之后的設計提出了一種思路。

國內IM對URL提取的處理

? ? 解讀:

? ? ? ? 目前對URL的提取思路基本上是先考慮是否存在協議部分(http,ftp等),如果存在協議部分,則認為此協議之后URL可以接受的部分都是URL。這種方式存在很大的缺陷,如http://1也會被識別為一個URL。而http:g.cn則不會識別為一個完整的URL。
對于不存在協議部分的情況,尋找www.,如果存在www.則認為此串為URL,如:www.1就會被識別為URL,而mp3.g.cn則不會識別為URL。以mp3.g.cn和www.g.cn為例,.cn為頂級域名,g.cn為一級域名,而mp3.g.cn和www.g.cn都是二級域名。由于一開始時,人們習慣將二級域名www.g.cn指向了一級域名g.cn,久而久之,人們就認為www.開頭的URL為一級域名。我想可能這個是造成目前這種判斷URL的邏輯的原因。

優缺點

  • 優點:
    • 邏輯簡單
    • 效率高
  • 缺點:
    • 判斷不準確

? ? ? ??產生以上優缺點的原因:只是尋找http,https,ftp,file,mailto,www這幾個關鍵詞。因為關鍵詞少,所以邏輯簡單也高效。有利有弊,因為關鍵詞少,也一定程度上影響了URL判斷的不準確性。

再次對URL進行分析和思考

? ? ? ? 常見的URL分類:

  • IP形式: 192.168.1.1,10.20.11.1
  • Domain形式:g.cn、www.g.cn,mp3.g.cn

? ? ? ? 觀察可以見得:IP形式的URL結構最為簡單:4個小于255的數字被.分割;domain形式比較復雜,但是它們有共性:都具有頂級域名.cn。

? ? ? ? 提取URL的大致思路:

? ? ? ? 通過以上的規律,可以發現,使用頂級域名來識別URL比使用協議或者www二級域名的方式要準確,同時輔助以IP鑒別,以求達到最大覆蓋。

對前人做了總結和分析后,以下是我設計的提取邏輯

  • 提取URL的基本邏輯

  • 案例:
原始文字提取結果
這個是g.cng.cng.co
g.com/index.htm?g.com/index.htm?s=g.cn
s=g.cn1.2.3.4561.2.3.45
g.cn和g.comg.cn
g.com
1.2.3.4.51.2.3.4
2.3.4.5

? ? ? ? 以上是設計的相關邏輯

  • 以下是我寫的一個demo的提取結果

  • 效率

最差URL形式

最優URL形式

URL形式

g.com.12.com.12.com.……

g.com/1111111111111……

遍歷次數

約 (n+1)*n/2(O(n^2))

約n(O(1))

URL長度

最差耗時(ms/10,000次查找)

最優耗時(ms/100,000次查找)

200

1529

400

410

3921

578

810

11703

953

1620

39463

1719

2450

82980

2453

3270

143151

3219

4300

266341

4141

優化

? ? ? ? 目前的代碼還是存在很多可以優化的地方:

? ? ? ? 因為我采用的遞歸調用,所以在最差情況下,執行效率大概是26ms一條,所以可以將遞歸改成循環來解決。

? ? ? ? 我使用的是C++類寫的,如果改成C并_fastcall調用約定也會快些。

? ? ? ? 目前這個邏輯大致思路是從頭到尾走一遍(不包括回溯),提取出以domain形式和IP形式的URL。在此之前,我設計成以domain形式從頭到尾檢測一次,和以IP形式從頭到尾檢測一次,然后綜合兩個結果的方法,這樣的設計會比我目前這樣的設計快一個數量級(已測)。

(轉載請指明出處)

總結

以上是生活随笔為你收集整理的一种精确从文本中提取URL的思路及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。