js版本正则表达式的模式匹配

/*正则表达式的模式匹配:
生成有向图的思路,(和|放进符号栈,遇到)从符号栈取符号,取到|后继续取(,需要加两条有向边,具体看代码;取到(的修改做索引,为当前循环里可能进行的*判断做准备。
对当前索引+1进行*判断,当前字符不是)则与当前索引创建两条边,如果是)则与栈里上一个(的索引创建两条边。
最后当前是()*的情况创建一条边到下一个索引,因为运算顺序是从左到右,|不加是因为|应该与右括号连接。
其他字符(如a,1)都不用加取下一个索引的边,识别的时候才加。否则只要txt最后一个字符在re里就能匹配。
*/

//用正则表达式文本生成有向图
function getGraph(re){
    let M=re.length
    let graph=[]								//用二维数组表示图
    for(let i=0;i<=M;i++){graph[i]=[]}
    let ops=[]									//符号栈
    for(let i=0;i<M;i++){
        let c=re[i]
        let left=i								//左索引
        if(c=='('||c=='|'){
            ops.push(i)
        }else if(c==')'){
            let or=ops.pop()					//中索引
            if(re[or]=='|'){
                left=ops.pop()
                graph[or].push(i)
                graph[left].push(or+1)
            }else if(re[or]=='('){
                left=or               //left给*做判断用的,只有*需要查看未来,索引是i+1
            }
        }
        if(i<M-1&&re[i+1]=='*'){            //i<M-1单纯为了防止越界
            graph[i+1].push(left)
            graph[left].push(i+1)
        }
        if(c=='('||c==')'||c=='*'){graph[i].push(i+1)}
    }
    console.log(JSON.stringify(graph))
    return graph
}


//在有向图graph里查找s能到达的所有点,放在list里返回
function dfs(graph,s,list=[]){
    list.push(s)
    for(let i in graph[s]){
        let c=graph[s][i]
        if(list.indexOf(c)==-1){
            //list.push(c)            //释放此行并注释list.push(s)会丢失第一个s
            list=dfs(graph,c,list)
        }
    }
    return Array.from(new Set(list))
}


//判断re能否匹配txt
function recognizes(txt,re){
    let graph=getGraph(re)
    var pc=dfs(graph,0)
    //console.log('start::::',JSON.stringify(pc))
    for(let t=0;t<txt.length;t++){
        let newpc=[]
        for(let i in pc){
            let v=pc[i]
            if(re[v]==txt[t]||re[v]=='.'){
                newpc=dfs(graph,v+1)
                //console.log('newpc:::',JSON.stringify(newpc),v+1)
            }
        }
        pc=newpc
        //console.log(t,JSON.stringify(pc))
    }
    for(let i in pc){
        if(pc[i]==re.length){return true}
    }
    return false
}


var re='(.*ab*((c|d*e)f)*g)'
var re1='((1|2)|8)'            //'(1|2|8)'拿不到正确的值
//let G=getGraph(re)
//let pc=dfs(G,3)
console.log(recognizes('bacfefdeg',re))					//false
console.log(recognizes('bacfefdefg',re))				//true
console.log(recognizes('bacfefdeffg',re))				//false
console.log(recognizes('1',re1))						//true
console.log(recognizes('2',re1))						//true
console.log(recognizes('8',re1))						//true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值