heavenm 发表于 2018-7-21 11:53:24

正则负向预取?!匹配模式的问题

本帖最后由 heavenm 于 2018-7-21 20:56 编辑

### 友情提示:本脚本由 Au3.REHelper 于 2018/07/21 12:16 自动生成,不保证其正确性,请自行测试 ###
#include <Array.au3>
Local $sSource = _
                'a111111111' & @CRLF & _
                'a22222222' & @CRLF & _
                'asdasdasdasd' & @CRLF & _
                '<test123sasdasd>' & @CRLF & _
                'a333333' & @CRLF & _
                'aasdasd' & @CRLF & _
                'a444444' & @CRLF & _
                'a555555' & @CRLF & _
                '<test2222asdasd>' & @CRLF & _
                'a6666666' & @CRLF & _
                'a777777'
;~MsgBox(0, '源字符串', $sSource)
Local $aSRE = StringRegExp($sSource, '(?s)(?!test123.*test2222)a\d+', 3)
If Not @Error Then MsgBox(0, '匹配数量: ' & UBound($aSRE), '其中元素为: ' & $aSRE)
_ArrayDisplay($aSRE, UBound($aSRE))

a111111111
a22222222
addsdf
asdasdasdasd
<test123sasdasd>
a333333
aasdasd
a444444
a555555
sadasd
sadasd
<test2222asdasd>
a6666666
a777777
a88888

Duvet 发表于 2018-7-21 22:07:54

本帖最后由 Duvet 于 2018-7-21 22:10 编辑

heavenm 发表于 2018-7-21 20:56
你说的逻辑漏洞是指啥,我试试看,代用到多的数据里试试看
如果數據來源出現兩組test2222的話,有可能會返回多餘的結果

Duvet 发表于 2018-7-21 21:50:15

你可以利用class值是固定的來找,href="(/product/\d+.html)">\s+<div class="img-box">

Duvet 发表于 2018-7-21 21:14:45

不用加(?s)啊,詳細的部分我再幫您看看

Duvet 发表于 2018-7-21 17:50:14

本帖最后由 Duvet 于 2018-7-21 18:07 编辑

用手機寫出來了,礙於手邊沒測試工具,請各位朋友幫忙測試一下,謝謝。

(?:test123.+\r\n(?:(?!a\d).*\r\n)*|\G(?<!\A)(?:(?!a\d).*\r\n)*)(a\d+)\r\n(?=[\s\S]+?test2222)
應該可以使用吧?
我發現這方式有個邏輯漏洞
還是推薦用兩步的方式呦

afan 发表于 2018-7-21 16:02:29

Duvet 发表于 2018-7-21 15:41
First:test123(.*)test2222
Second:a\d+
來看看afan有沒有更好的解法

大师都看不懂,我更懵逼了…
从期望的结果来判,LZ的正则肯定不对
这种情况下,我一般也同大师一样,采取分步匹配的方式,既对效率有好处,且易懂易改

heavenm 发表于 2018-7-21 11:54:13

本帖最后由 heavenm 于 2018-7-21 12:07 编辑

匹配的内容不对

应该只匹配到3条才对

a333333
a444444
a555555

lpxx 发表于 2018-7-21 13:35:33

你这个问题怕是afan的回答才比较权威。

Duvet 发表于 2018-7-21 15:12:20

本帖最后由 Duvet 于 2018-7-21 15:26 编辑

我也看不懂,坐等afan
(?s)(?!test123.*test2222)a\d+
後面不含test123到test2222的文字,並截取以a開頭數字結尾的字串
結果卻是含test123到test2222的文字,這不是很矛盾嗎?


Duvet 发表于 2018-7-21 15:41:53

本帖最后由 Duvet 于 2018-7-21 15:43 编辑

First:test123(.*)test2222
Second:a\d+
來看看afan有沒有更好的解法

heavenm 发表于 2018-7-21 16:39:04

afan 发表于 2018-7-21 16:02
大师都看不懂,我更懵逼了…
从期望的结果来判,LZ的正则肯定不对
这种情况下,我一般也同大师一样,采 ...

连A版都搞不定,看来一句代码搞不定,只能分步操作了!我以为可以一步到位{:1_492:}

heavenm 发表于 2018-7-21 16:39:55

脑壳都想疼了,我发现我总会纠结这种问题哈哈!总想一句代码搞定!

Duvet 发表于 2018-7-21 17:00:06

大師是您才對。一行好像可以又好像不行,我再想想

fang5072546 发表于 2018-7-21 17:08:14

本帖最后由 fang5072546 于 2018-7-21 17:10 编辑

你这个问题很好解释啊,首先,抛开?!语法不说,你有自己测试过(?s)(test123.*test2222)这句匹配的内容?自己可以用
(?s)(?!test123.*test2222).*测试,发现除了<以外的所有字符都在匹配范围,换句话说,你其实寻找的条件是你那字符串除了<之外的所有字符串中查找a开头,后面紧跟着任意数字的字符,很显然,所有带a的都匹配上了,这是意料之中.
关于4楼说的矛盾,其实你这样去理解就可以茅塞顿开了.假设有一段话,
我是正则表达式测试    你要找的是<!正则表达式测试>.正则表达式是一个个字符串去跟条件匹配的,虽然我们的表达式是多个字符串,但是正则表达式在匹配的时候,其实是把他解释为单个字符串的.具体的可以找个带DEBUG的工具,看看回溯机制以及匹配次数就知道了.正则表达式在执行的时候,就会检索,从我开始,发现后面不是正则表达式测试,那么他就匹配上了,然后从是开始,发现后面是正则表达式测试,这时候他就会标记是为未匹配,然后从正开始,正后面跟的是则表达式,并不是我们的条件正则表达式,所以正也匹配上了,以及类推,则,表..所以我们的语句最终的匹配结果是我正则表达式测试.

heavenm 发表于 2018-7-21 20:56:25

Duvet 发表于 2018-7-21 17:50
用手機寫出來了,礙於手邊沒測試工具,請各位朋友幫忙測試一下,謝謝。

(?:test123.+\r\n(?:(?!a\d).*\r ...

你说的逻辑漏洞是指啥,我试试看,代用到多的数据里试试看

heavenm 发表于 2018-7-21 21:08:52

Duvet 发表于 2018-7-21 17:50
用手機寫出來了,礙於手邊沒測試工具,請各位朋友幫忙測試一下,謝謝。

(?:test123.+\r\n(?:(?!a\d).*\r ...

代入到复杂的代码里面好像不行不知道是不是我写得有问题(?s)(?:product-list-wrapper.+\r\n(?:(?!/product/\d).*\r\n)*|\G(?<!\A)(?:(?!/product/\d).*\r\n)*)(/product/\d+.html)\r\n(?=[\s\S]+?product-list-pager)

heavenm 发表于 2018-7-21 21:17:27

(/product/\d+.html).*\r\n(?=[\s\S]+?product-list-pager)
只用最后一段,第一条多匹配到一条数据
页: [1] 2
查看完整版本: 正则负向预取?!匹配模式的问题