【學渣】字元匹配之有限狀態自動機--應用在爬蟲程式中匹配網址
阿新 • • 發佈:2019-02-06
關於自動機的原理的文章已經有很多了,我就不再多說了,我覺得很多部落格都寫的很好
我就寫一下在網址匹配方面的應用吧
其實很多人大都會選擇正則表示式
如果是有規律的匹配,應該有一個狀態轉移函式,但是我沒有為下圖找到規律,所以就用了最蠢的方法
如果是連續的輸入,比如abababcrfjg這樣的模式,然後輸入的主字串也是連續的 就可以寫出來一個看起來不蠢的函式
隨便開啟一個網頁,看看它的原始碼
然後根據上面的圖
我們可以寫出來一個矩陣,或者叫表
state | < | > | a | h | r | e | f | = | " | / | 其他 | |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 2 | 0 | 2 | 3 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
3 | 2 | 0 | 2 | 2 | 4 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
4 | 2 | 0 | 2 | 2 | 2 | 5 | 2 | 2 | 2 | 2 | 2 | 2 |
然後就可以寫程式了
#include<stdio.h> #include<string.h> void main() { int state=0; char url[102400]; printf("input url:\n"); gets(url); //scanf("%s",url); printf("input successfully,url is :\n%s\n",url); int len_url=strlen(url); printf("lenth is :%d\n",len_url); int flag=0; for(int i=0;i<=len_url;i++) { //printf("for***[%d]**state=%d****url[%d]=%c\n",i,state,i,url[i]); if(state==0){if(url[i]=='<'){state=1;continue;}else {state=0;flag=i;continue;}} if(state==1){if(url[i]=='a'){state=2;continue;}else {state=0;flag=i;continue;}} if(state==2) { if(url[i]=='h'){state=3;continue;} if(url[i]=='>'){state=0;flag=i;continue;} else{state=2;continue;} } if(state==3) { if(url[i]=='r'){state=4;continue;} if(url[i]=='>'){state=0;flag=i;continue;} else{state=2;continue;} } if(state==4) { if(url[i]=='e'){state=5;continue;} if(url[i]=='>'){state=0;flag=i;continue;} else{state=2;continue;} } if(state==5) { if(url[i]=='f'){state=6;continue;} if(url[i]=='>'){state=0;flag=i;continue;} else{state=2;continue;} } if(state==6) { if(url[i]=='='){state=7;continue;} if(url[i]=='>'){state=0;flag=i;continue;} else{state=2;continue;} } if(state==7) { if(url[i]=='"'){state=10;continue;} if(url[i]==' '){state=7;continue;} else{state=0;flag=i;continue;} } if(state==10) { if(url[i]=='/'){state=8;continue;} if(url[i]=='"'||url[i]=='>'||url[i]=='#'){state=0;flag=i;continue;} else{state=10;continue;} } if(state==8) { if(url[i]=='>'){state=0;flag=i;continue;} if(url[i]=='"') { state=9; for(int j=flag;j<=i;j++) {printf("%c",url[j+1]);} printf("\n\n"); continue; } if(url[i]!='>'&&url[i]!='"'&&state==8){state=8;continue;} } if(state==9) { state=0;continue; } else continue; } }