正则表达式-分隔符示例

说明

文本中经常需要匹配分隔符内的内容,像程序中的注释以/*开头,*/结尾;双引号""内的字符等,我们今天以这个例子来一步步的构建这个正则表达式

我们以""来作示例

一 凭直觉

可以简单写为"[^"]*"
对于处理"haha haha"这种的足够了, 不过如果有转义斜线\怎么处理?就是对于"\"This is Tom\" he said",我们只会先匹配到\,但在语义上与我们要匹配的不符合

二 环视

可以采用环视,\"认为是正常文本,这样表达式写为"([^"]|(?=\\)")*"

三 转义字符

对于上面的表达式,我们如果匹配 "hello there \\" else "hello world" 按上面例子匹配到else后的",问题是\是被转义的,匹配到这里是不对的。 考虑到\\是成对出现的,\后面的字符都是被转义的,具体是什么其实无所谓, 我们可以以反斜线后面跟一个点号来匹配这样的内容,写为"(\\.|[^"])*"

四 不匹配的字符串

我们再来构造一个不应该匹配的串: "hello there \2\3" and world 按照三种的正则式会匹配出来hello there \2\3\, 在\\.匹配后,到最后没有找到后面的",所以会回溯到\"\匹配[^"], "匹配最后的" 从这我们看到在后面中括号里面也不应该包括反斜线,把它去掉,改写为:"((\\.)|[^\\"])*"

五 效率问题

这个式子就可以了,不过效率不够好,因为反斜线转义的字符在前面,但是普通字符出现的频率比反斜线转义的字符要高,引擎在传动之后发现不匹配就需要回溯,造成了很多的浪费,我们来换一下位置变为:"([^\\"]|(\\.))*"

六 占有优先量词和固化分组

如果我们使用占有优先量词和固化分组更好一点,这样在三中出现的问题就没有问题了,因为占有优先量词在回溯时不会交还字符,而是直接报错. "(\\.|[^"])*+" \\.匹配的字符不会交还,就不会出问题 "((?>\\.)|[^"])*""(?>(\\.|[^"])*)" 这两种应该都可以

七 总结

总结两点 1:要深刻理解回溯,多选结构匹配出来的结构可能并不是我们想要的。 2:多写注释,后面自己都忘了当时为什么要写这么复杂了,其实写完再看四或六中的表达式对于当时是怎么思考的已经忘的差不多了,但是文档却会让我们的思考变得有迹可循。

转载于:https://my.oschina.net/liufq/blog/1812894

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值