. : : ClassiClub ForuM : : .

会员中心 论坛帮助 日历事件 标记论坛已读
返回   精品技术论坛 » 技术论坛 » 『软件使用』

『软件使用』: 电脑软件推荐, 电脑软件使用, 经验分享



发表新主题 回复
 
主题工具
boyyao
 
boyyao 的头像
核心会员
 
资 料:
注册日期: Sep 2000
帖子: 2,404 声望值: 3
精华: 1,解答: 1
#1 旧 2021-11-28, 23:44:50 默认 【讨论】正则库不支持逆向断言的可变长,有何变通的方法?
boyyao 当前离线  

Perl兼容系的正则表达式库,不支持逆向断言(Lookbehind)的可变长,有没有变通的方法解决?
比较了一下,貌似只有微软系的.NET库支持无限可变长的逆向断言。

举个栗子:
代码:
(?<=@{\s*\[.*)
(?<![$@])
(?:
 %(?:\w+ | [-+!]\B | \^[A-Z]\b)
  |
 %(?=[{$^]) (?:{\w+})?
)
(?=.*\]\s*})


匹配结果如图:
11.png



上例.NET环境下达到预期,但在其它系正则库里报错,因为用了变长逆向断言:
代码:
(?<=@{\s*\[.*)


有没有可变通的方法来实现同样的变长逆向断言?



虽然上面的栗子可用以下方法来变通:
为方便测试,正则简化了:
代码:
(?!.*@\{\s*\[) % (?=.*\]\s*\})
但若省去后面的顺视断言,匹配结果出入可就大了。






__

此帖于 2021-12-01 16:20:09 被 boyyao 编辑. .


---------------------
当午当午我是锄禾
回复时引用此帖
MacOS
 
MacOS 的头像
热心会员
 
资 料:
注册日期: Aug 2002
帖子: 13,486 声望值: 5
精华: 0,解答: 129
#2 旧 2021-11-29, 09:29:22 默认
MacOS 当前离线  

反向预取居然有引擎支持通配符?虽然不知道你写这么复杂的正则干嘛,俺之前常用的软件没试出过这个特性


HIDDEN MESSAGE LEVEL 3
14863 159357 789 159357 3245687 3684
回复时引用此帖
MacOS
 
MacOS 的头像
热心会员
 
资 料:
注册日期: Aug 2002
帖子: 13,486 声望值: 5
精华: 0,解答: 129
#3 旧 2021-11-29, 09:50:57 默认
MacOS 当前离线  

请给个例子,最好把前后的规则也补一下,现在截取的规则一个实体字符都没有,全预取
回复时引用此帖
judite
 
judite 的头像
热心会员
 
资 料:
注册日期: Jan 2001
帖子: 2,566 声望值: 8
精华: 2,解答: 31
#4 旧 2021-11-29, 11:49:27 默认
judite 当前在线  

好复杂的正则……为什么我不能看到匹配结果
回复时引用此帖
laokai
 
laokai 的头像
合作伙伴
 
资 料:
注册日期: Apr 2008
帖子: 2,927 声望值: 8
精华: 0,解答: 1
#5 旧 2021-11-29, 12:23:08 默认
laokai 当前离线  

看不懂呀
真的帮不上忙,过
回复时引用此帖
boyyao
 
boyyao 的头像
核心会员
 
资 料:
注册日期: Sep 2000
帖子: 2,404 声望值: 3
精华: 1,解答: 1
#6 旧 2021-11-29, 19:17:45 默认
boyyao 当前离线  

引用:
作者: MacOS 查看帖子
反向预取居然有引擎支持通配符?虽然不知道你写这么复杂的正则干嘛,俺之前常用的软件没试出过这个特性

请给个例子,最好把前后的规则也补一下,现在截取的规则一个实体字符都没有,全预取
有的,唯数不多,微软.NET一系支持,Chrome的v8貌似也支持。
没干啥正经的事,常用的一款编辑器内置语法加亮稍显简陋,昨天心血来潮想给强化下细节。

上面例子就是其中一条完整的匹配规则了。
前后两个断言锚定 @{[ 和 ]},然后匹配出里面的各种字面上合法的hash形态。

正则调试工具推荐 RegexBuddy, 支持各系的正则引擎库切换,比较全。

当然这里的重点不是讨论上面这个举例本身,而是想讨论下,
对于逆向断言不支持通配可变长的正则库, 如何较完美的去变通实现同样的功能。




__

此帖于 2021-11-29 19:34:50 被 boyyao 编辑. .
回复时引用此帖
MacOS
 
MacOS 的头像
热心会员
 
资 料:
注册日期: Aug 2002
帖子: 13,486 声望值: 5
精华: 0,解答: 129
#7 旧 2021-12-01, 08:28:54 默认
MacOS 当前离线  

有点明白你的意思了,你的原式应该有部分错误或特例,反推测试时始终通不过简化式
具体还是要给个例子,俺也看不到图,仅凭这两句话没法反推出详细的例子
引用:
前后两个断言锚定 @{[ 和 ]},然后匹配出里面的各种字面上合法的hash形态。
你的简化式有使用条件,第一部分(?!.*@\{\s*\[)并没有锚定@{[,只是排除了,无开头也成立的,具体还是得看例文,但推测的结果也不好,只能用替换不能全预取

单说到问题,正向和反向分别是字串前后位置,落点完全不同,试不出替代的方法
回复时引用此帖
boyyao
 
boyyao 的头像
核心会员
 
资 料:
注册日期: Sep 2000
帖子: 2,404 声望值: 3
精华: 1,解答: 1
#8 旧 2021-12-01, 16:35:51 默认
boyyao 当前离线  

确实, 简化的测试式有问题, 这条变通有Bug。


原式锚定范围:
代码:
(?<=@\{\s*\[.*)  .*  (?=.*\]\s*\})
0.png




前锚定改用顺视否定:

代码:
(?!.*@\{\s*\[)  .*  (?=.*\]\s*\})
1.png




但若目标文本不存在前锚定目标,就与预期不符了。。
2.png







__
回复时引用此帖
jimmy_dong
 
jimmy_dong 的头像
管理员
 
资 料:
注册日期: Aug 2000
帖子: 5,428 声望值: 9
精华: 2,解答: 89
#9 旧 2021-12-01, 17:21:44 默认
jimmy_dong 当前离线  

反向断言不支持可变是因为可能导致死循环。估计.net限制了匹配层级深度。

你这个例子里面体现不出来用通配符有什么意义。

从工程上讲,如果遇到需要可变长反向断言的,可以通过两个方式解决:

1,非否定的反向断言改写为普通的匹配,目标部分加括号,结果集中取需要的目标部分

2,否定的,分成两步: 先做一次匹配,结果中再做一次匹配筛掉不符合的



~~呵呵~~


……你呀,考虑一下吧,要快一点,你知道,肚子很快又饿了。 jimmy_dong@sina.com Oicq:816937

如果失去了“呵呵”,生活会是怎样?
回复时引用此帖
MacOS
 
MacOS 的头像
热心会员
 
资 料:
注册日期: Aug 2002
帖子: 13,486 声望值: 5
精华: 0,解答: 129
#10 旧 2021-12-02, 10:29:01 默认
MacOS 当前离线  

引用:
作者: boyyao 查看帖子
确实, 简化的测试式有问题, 这条变通有Bug。


原式锚定范围:
代码:
(?<=@\{\s*\[.*)  .*  (?=.*\]\s*\})
附件 948523




前锚定改用顺视否定:

[COD......
如果你规则很固定,预取\[和]就够了,有比较大限制条件,但实现简单
如果你必须原式,那可以考虑9楼的前提,反向预取自己手动预测深度,这个条件最少,也最不影响,缺点是深度控制死了,而且可能很长
例如(?<=@{\s{1,3}\[),写并列
((?<=@{\s\[)|(?<=@{\s\s\[)|(?<=@{\s\s\s\[))
回复时引用此帖
boyyao
 
boyyao 的头像
核心会员
 
资 料:
注册日期: Sep 2000
帖子: 2,404 声望值: 3
精华: 1,解答: 1
#11 旧 2021-12-02, 20:14:23 默认
boyyao 当前离线  

如果是代码层面考虑方法多的是, 大不了分两次匹配,哈。

我也是看到有少数正则引擎的逆向断言能够支持变长通配,觉得此功能实用缺失了可惜,
才开此贴, 可能我钻牛角尖了。 ,,,

就如上面首例的附图处,若要求一条正则回溯匹配出特定范围内的所有符合要求的HASH变量,
若非有无限变长逆向断言,我真想不出解决之道。



_
回复时引用此帖
发表新主题 回复

标签
regex

主题工具

论坛规则  发帖规则
不可以发表主题
不可以回复帖子
不可以上传附件
不可以编辑自己的帖子
论坛启用 vB 代码
版面启用 表情符号
版面启用 [IMG] 代码
版面禁用 HTML 代码


所有时间均为北京时间, 现在的时间是 18:34:24.

本论坛带宽由迅通网络提供
SSL证书由TrustAsia提供

Copyright © 2000 - 2021 ClassiClub Forum All Rights Reserved.
CCF@WORLD