条件表达式

当前位置:首页>正则>条件表达式

条件表达式

Sub 条件分支()
'1. (?(n)yes|no) - 根据捕获组是否被捕获
'示例:匹配单词或引号内的单词
'(?:"([^"]+)"|(\w+))(?(1)\1|\2)
'  解释:
'  "([^"]+)":捕获引号内的内容为 $1
'  (\w+):捕获普通单词为 $2
'  (?(1)\1|\2):如果 $1 已匹配(即有引号),则返回 $1 的内容;否则返回 $2 的内容

'2. (?(+n)yes|no) - 根据相对编号捕获组是否被捕获
'语法:如果相对编号为 +n 的捕获组已被捕获,则匹配 yes;否则匹配 no
'示例: 匹配交替出现的字母
'目标:匹配交替出现的字母对,如 ABAB,但只捕获奇数位字母
'^(\w)(\w)(?(+1)\1|\2)$

'3. (?(<name>)yes|no) - 根据具名捕获组是否被捕获
'示例:匹配不同的引号类型
'目标:匹配单引号 ' 或双引号 " 包围的内容
'(?<quote>'([^']+)')|(?<quote>"([^"]+)")(?(quote)\1|\2)
'  解释:
'  (?<quote>'([^']+)'):捕获单引号内的内容为 $1,并命名为 quote
'  (?<quote>"([^"]+)"):捕获双引号内的内容为 $2,同样命名为 quote
'  (?(quote)\1|\2):检查是否捕获了 quote 组。如果是(即匹配了单引号),返回 $1;否则返回 $2

'4. (?(R)yes|no) - 根据整体递归是否匹配
'示例:匹配平衡的嵌套结构
'目标:匹配平衡的圆括号 ((())),并检查是否存在递归嵌套
'\((?:(?(R)\((?R)\))|[^()]*)\)
'  解释:
'  \(:匹配左圆括号
'  (?(R)\((?R)\)):如果检测到递归(即内部还有括号),则匹配嵌套结构 ((?R))
'  |[^()]*):否则匹配非括号字符
'  \):匹配右圆括号

'5. (?(Rn)yes|no) - 根据特定编号分支递归是否匹配
'示例:匹配特定层级的嵌套
'目标:匹配至多两层嵌套的方括号 [[1]],并检查是否超过两层
'\[(?:(?(?2)\[(?R)\])|[^\[\]]*)\]
'  解释:
'  \[:匹配左方括号
'  (?(?2)\[(?R)\]):如果检测到第二层递归(?2),则匹配嵌套结构 [(?R)]
'  |[^\[\]]*):否则匹配非方括号字符
'  \]:匹配右方括号

'6. (?(R&name)yes|no) - 根据特定具名分支递归是否匹配
'示例:匹配特定标签的嵌套
'目标:匹配 HTML 中 <div> 标签的嵌套,并检查是否存在嵌套
'(?<div><div>(?:(?(R&div)<div>(?R)</div>)|[^<]*)</div>)
'  解释:
'  (?<div>...):定义一个名为 div 的分支
'  (?:(?(R&div)<div>(?R)</div>)|[^<]*):如果检测到 div 分支递归成功(即存在嵌套 <div>),则匹配嵌套结构;否则匹配非标签字符

'7. (?(DEFINE)yes|no) - 定义子表达式(仅用于定义,不匹配)
'示例:定义复用的模式
'目标:定义一个复用的数字模式 NUM,用于后续匹配
'(?|(?(DEFINE)(?<NUM>\d+))\b(?&NUM)\b)
'  解释:
'  (?(DEFINE)(?<NUM>\d+)):在 DEFINE 中定义一个名为 NUM 的捕获组,匹配数字
'  \b(?&NUM)\b:在后续模式中引用 NUM,匹配完整的数字单词

'8. (?(VERSION[>]=n[.m])yes|no) - 根据 PCRE2 版本条件匹配
'语法:如果当前 PCRE2 版本满足条件,则匹配 yes;否则匹配 no。
'示例: 版本特性检测
'目标:根据 PCRE2 版本决定是否使用特定的语法。
'逻辑:如果版本大于等于 10.30,则匹配 yes 部分(使用新语法);否则匹配 no 部分(使用旧语法)。
'(?(VERSION>=10.30)\b\w+(?R)\b|\b\w+\b)
'解释:
'(VERSION>=10.30):检查 PCRE2 版本是否大于等于 10.30。
'\b\w+(?R)\b:如果是新版本,使用递归模式匹配单词。
'\b\w+\b:如果是旧版本,使用普通单词匹配。

'9. (?(assert)yes|no) - 根据断言结果条件匹配
'语法:如果断言 assert 成功,则匹配 yes;否则匹配 no。
'示例: 正向前瞻条件
'目标:匹配单词 test,但仅当其后面跟随数字 123 时才匹配。
'逻辑:使用前瞻断言检查后续内容,如果成功则匹配 yes 部分(test123),否则匹配 no 部分(仅 test)。
'test(?(?=123)123|)
'  解释:
'  (?=123):前瞻断言,检查 test 后面是否跟随 123。
'  (?(?=123)123|):如果断言成功,匹配 123;否则不匹配任何字符(空)。
End Sub

------------------------------------------------------------------------------

Sub 条件表达式()
    
    '1、捕获组条件
    ' `(?(1)yes-pattern|no-pattern)` - 如果第1个捕获组已匹配则使用yes-pattern
    ' `(?(<name>)yes-pattern|no-pattern)` - 如果名为name的捕获组已匹配则使用yes-pattern
    reg.Pattern = "(\()?abc(?(1)\)|123)"
    Debug.Print reg.Execute("(abc)123")(0).Value  '匹配(abc)
    Debug.Print reg.Execute("abc123")(0).Value    '匹配abc123
    
    '2、递归条件
    ' `(?(R)yes-pattern|no-pattern)` - 如果正在递归则使用yes-pattern
    ' `(?(R1)yes-pattern|no-pattern)` - 如果正在递归第1个组则使用yes-pattern
    
    '3 断言条件
    ' `(?(?=assertion)yes-pattern|no-pattern)` - 前瞻断言为真时使用yes-pattern
    ' `(?(?!assertion)yes-pattern|no-pattern)` - 负前瞻断言为真时使用yes-pattern
    reg.Pattern = "(?(?=\d)123|abc)"
    Debug.Print reg.Execute("password123").Count  '非数字开头,不匹配
    Debug.Print reg.Execute("2123abc")(0).Value   '数字开头,匹配123
    Debug.Print reg.Execute("123abc")(0).Value    '数字开头,匹配123
    
End Sub