easefull 发表于 2011-3-16 05:22:23

[已解决]AutoIt正则表达式——捕获'(exp)和(?:exp)'的疑惑

本帖最后由 easefull 于 2011-4-18 01:59 编辑

假设有一个字符串Local $sString = "You deflect 36 of Gnarly Monster's 279 damage"要提取damage前的数值279(假设字符串里面的两个数字都是0~999范围内);代码一
#include <Array.au3>
Local $sString = "You deflect 36 of Gnarly Monster's 279 damage"
$asResult = StringRegExp($sString, '\d?\d?\d(?:\sdamage)', 1)
If Not IsArray($asResult) Then
        MsgBox(4096, "", "返回结果非数组" &@LF& $asResult)
Else
        _ArrayDisplay($asResult)
EndIf在代码一里面,可以取得到包含279的字符串 "279 damage"

我的问题是:为什么正则参数里面加了一对括号以后,结果就不一样了呢?(代码二);代码二
#include <Array.au3>
Local $sString = "You deflect 36 of Gnarly Monster's 279 damage"
$asResult = StringRegExp($sString, '(\d?\d?\d)(?:\sdamage)', 1)
If Not IsArray($asResult) Then
        MsgBox(4096, "", "返回结果非数组" &@LF& $asResult)
Else
        _ArrayDisplay($asResult)
EndIf注:我使用Code Architects Regex Tester测试的时候,加不加括号结果都是一样的

3mile 发表于 2011-3-16 11:17:14

(?: ... ) 非捕获组. 仅工作于正常组, 但是不记录数组的匹配字符
被匹配的文本也不会用作后向引用

easefull 发表于 2011-3-16 14:16:02

本帖最后由 easefull 于 2011-3-16 14:33 编辑

回复 2# 3mile

我想我能明白捕获的意思——把()里面匹配的内容保存到一个分组,并分配组号,可以使用这个组号来做后向引用.
在StringRegExp标志=3的时候还会把()匹配的内容保存到数组;捕获
#include <Array.au3>
$sString = 'test'
$sRegExp = '(te(st))'
$asResult = StringRegExp($sString, $sRegExp, 3)
If @error Then
        MsgBox(4096, "", "返回结果非数组" &@LF& $asResult)
Else
        _ArrayDisplay($asResult)
EndIf;不捕获
#include <Array.au3>
$sString = 'test'
$sRegExp = '(te(?:st))'
$asResult = StringRegExp($sString, $sRegExp, 3)
If @error Then
        MsgBox(4096, "", "返回结果非数组" &@LF& $asResult)
Else
        _ArrayDisplay($asResult)
EndIf但我不能理解"捕获组"和"正常组"的区别.
也不能理解我在一楼那里面的问题:
我的理解是:
'\d?\d?\d(?:\sdamage)'红色部分没有括号,在这里匹配并包含了\sdamage
'(\d?\d?\d)(?:\sdamage)'这样,红色部分多了个括号是捕获了279,也分了组号1.后面没有调用组号,不是后向引用.但为什么结果里面不包含\sdamage

按我的理解,不管加不加括号,结果总应该包含\sdamage才对.想这问题我都有些晕了.
而更让我郁闷的是,用Regex Tester匹配这个问题,加不加括号结果都是一样的——这和Au3匹配的结果可不一样——于是乎,我彻底魔障了!

3mile 发表于 2011-3-16 14:40:44

回复 3# easefull
'\d?\d?\d(?:\sdamage)'红色部分没有括号,在这里匹配并包含了\sdamage
这里分组了吗?没有吧.所以'非捕获组'不工作

'(\d?\d?\d)(?:\sdamage)'这样,红色部分多了个括号是捕获了279,也分了组号1.后面没有调用组号,不是后向引用.但为什么结果里面不包含\sdamage
这里分组了,所以'非捕获组'工作,于是非捕获组不记录所匹配的内容

easefull 发表于 2011-3-16 18:14:24

回复 4# 3mile

还是有些迷迷糊糊的,但又好像明白了.
看样子是我的正则观念有错误,我得先去重新学过分组这一部分的正则,再回过头了看这个.谢谢您的指点.

pchome2000 发表于 2011-7-2 14:19:12

正则表达式很强大            {:face (190):}

sleep365 发表于 2012-10-31 15:53:14

这个还是有点意思啊。
页: [1]
查看完整版本: [已解决]AutoIt正则表达式——捕获'(exp)和(?:exp)'的疑惑