递归正则与负前瞻结合匹配异常问题求助
修复多字符括号的递归正则匹配问题
原正则^begin(?:(.+)(?!egin)|(?R))*end$的核心问题在于:
.+是贪婪匹配,会一次性吃掉大量内容,后续的(?!egin)仅检查当前匹配的末尾位置,无法阻止中间出现未闭合的begin- 逻辑上没有正确区分“嵌套的begin...end”和“普通内容”,导致错误匹配了
beginmbeginmmend这类不合法的字符串
重写后的正则
^begin(?:(?:(?!begin|end).)+|(?R))*end$
搭配s修饰符(让.匹配所有字符,包括换行)使用。
测试验证
# 验证合法嵌套字符串(应替换为well) echo begin_deep_begin_deepest_end_deep_end | perl -pe 's/^begin(?:(?:(?!begin|end).)+|(?R))*end$/well/s' # 输出:well # 验证非法字符串(应保留原内容) echo beginmbeginmmend | perl -pe 's/^begin(?:(?:(?!begin|end).)+|(?R))*end$/well/s' # 输出:beginmbeginmmend
正则逻辑拆解
^begin:匹配字符串开头的begin标记(?:(?:(?!begin|end).)+|(?R))*:循环匹配两种内容:(?:(?!begin|end).)+:逐个匹配任意字符,但确保当前位置不是begin或end的起始(通过负前瞻(?!begin|end)避免误嵌套)(?R):递归匹配整个正则表达式,处理嵌套的begin...end结构
end$:匹配字符串结尾的end标记s修饰符:让.可以匹配换行符,适配包含换行的嵌套场景
内容的提问来源于stack exchange,提问作者Daniil Iaitskov
相关产品推荐
相关产品推荐

