适应adblock plus 规则的简单正则表达式匹配

简介: adblock plus定义的广告过滤列表非常好用,这里分析一下adblock plus的广告过滤规则 ! 开始表示注释 * 通配符,匹配任何字符串 @@ 以此开头表示白名单, | 以此开始或者结束表示开始处或者结束处严格匹配,没有其他内容了 || 以此开头会忽略协议规则进行匹配,比如忽略http,https等 ^ 分隔符匹配除数字,字母,-,.,%以外的其他字符 $ 指明后面的是过滤类型,比如是是image还是script等   按照adblock plus的说法,这些最终都转换成了正则表达式来处理,具体怎么实现不是很清楚。

adblock plus定义的广告过滤列表非常好用,这里分析一下adblock plus的广告过滤规则

开始表示注释

* 通配符,匹配任何字符串

@@ 以此开头表示白名单,

| 以此开始或者结束表示开始处或者结束处严格匹配,没有其他内容了

|| 以此开头会忽略协议规则进行匹配,比如忽略httphttps

^ 分隔符匹配除数字,字母,-.,%以外的其他字符

$ 指明后面的是过滤类型,比如是是image还是script

 

按照adblock plus的说法,这些最终都转换成了正则表达式来处理,具体怎么实现不是很清楚。

对于大多数情况来说运行最耗时间的就是匹配问题,类型,以及协议信息可以根据url分析出来,很容易分离,

因此这里重点介绍如何实现最核心的*^的匹配,通过一个patternStep来减小嵌套次数

/*

  get a much bigger step for *.

  */

static inline int  patternStep( const char * s, const  char * p)

{

    //这里可以根据下一个字符多跳几个

    char temp[8];

    int step=0;

    const char * t=p;

    while(*t!='*' && *t!='^' && *t!='\0')

    {

        step++;

        t++;

    }

    if(!step) //防止只有一个通配符的情况比如^,*

        return 1;

    memset(temp,0,sizeof(temp));

    strncpy(temp,p,min(sizeof(temp)-1,step));

    printf("temp=%s,step=%d\n",temp,step);

    const char * res=strfind(s,temp);

    if(!res) //没有找到

        return strlen(s); //移动真整个字符串

    else

        return max(1,res-s); //找到第一个匹配的字符串的位置

}

/*

   test if a given string  and a pattern  matches use adblock plus rule

   give a string s and a pattern p ,

   if they match,return 1, then return 0

   */

bool adbMatch(const char *  s,  const char *  p,bool caseSensitivie=true) {

    for (;;) {

        switch(*p++) {

            case '*' :  // match 0-n of any characters

                //这里可以根据下一个字符多跳几个

                if (!*p) return true; // do trailing * quickly

                while (!adbMatch(s, p,caseSensitivie))

                {

                    if(!*s) return false;

                    s+=patternStep(s,p);

                }

                return true;

            case '^':

                if(isSeperator(*s))

                {

                    s++;

                    break;

                }

                else

                    return false;//expect a sepetor,

            case '\0':  // end of pattern

                return !*s;

            default  :

                if (getCaseChar(*s++,caseSensitivie) !=

                    getCaseChar(*(p-1),caseSensitivie)) return false;

                break;

        }

    }

}

目录
相关文章
|
Java 编译器
正则表达式规则
Java中的正则表达式规则,如何写正则表达式?
75 0
|
5月前
|
人工智能 Java 数据格式
JavaSE——正则表达式(1/2):概述、初步使用(普通方法,正则表达式)、书写规则(字符类,预定义字符,数量词,其他,特殊案例)
JavaSE——正则表达式(1/2):概述、初步使用(普通方法,正则表达式)、书写规则(字符类,预定义字符,数量词,其他,特殊案例)
47 3
正则表达式的详细规则
正则表达式的详细规则
237 1
|
运维 Java 应用服务中间件
【Nginx用法】nginx location正则表达式写法,详解Nginx location 匹配规则(很详细哦)
【Nginx用法】nginx location正则表达式写法,详解Nginx location 匹配规则(很详细哦)
344 0
|
机器学习/深度学习 Shell C++
正则表达式普通字符、非打印字符、特殊字符、限定符的应用、定位符、元字符(规则,匹配,和实际使用)与运算符优先级
正则表达式普通字符、非打印字符、特殊字符、限定符的应用、定位符、元字符(规则,匹配,和实际使用)与运算符优先级
283 0
正则表达式——常用的匹配规则
简介:正则表达式——常用的匹配规则
正则表达式——常用的匹配规则
|
Python
Python之HTTP状态码、正则表达式语法规则
一、HTTP状态码归总 100:继续  客户端应当继续发送请求。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应 101: 转换协议  在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。
1630 0
|
5月前
|
数据库 Python
Python网络数据抓取(8):正则表达式
Python网络数据抓取(8):正则表达式
56 2