条件表达式

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

条件表达式

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