- 每次使用都需要查阅手册熟悉规则
- 每次使用都是痛苦的在一边看手册一边修改(重复猜测-验证的过程)
- 常常写的正则逻辑上分析找不到问题却为何无法匹配
调出功能的意义
调出功能相当于在这个黑箱子上打孔,这样我们可以观察到里面是怎样进行匹配的。
Code: Select all
Source := "Haystack[c]nxyz[/c]nabc"
FoundPos := RegexMatch(Source, "m)xyz$")
MsgBox, % FoundPos
Code: Select all
Source := "Haystack[c]nxyz[/c]nabc"
FoundPos := RegexMatch(Source, "m)xyz(?CCallout)$")
MsgBox, % FoundPos
Callout(m) {
MsgBox, m=%m%
}
顺便和大家分享个小技巧:在使用 m 选项时尽量搭配 `a 选项,保证你会省却很多麻烦。这里的换行符我们可以直接看到,较容易发现,实际的情况就复杂了,如:
Code: Select all
Source =
(
Haystack
xyz
abc
)
返回值的用途
在 AutoHotkey 中,目前 RegExMatch() 和 RegExReplace() 都支持调出功能,这里简单说说它们具体是如何支持的。
在调出函数中这个参数最重要,默认保存了对应调出插入点之前那部分模式所匹配的字符串(若有子模式则存于伪数组),通过 P 或 O 选项分别可保存位置和长度、匹配对象。下面看看调出函数的返回值。正则表达式调出 wrote:调出函数最多可以定义 5 个参数:
- Match: 相当于 RegExMatch 中的 UnquotedOutputVar,包含需要时数组变量的创建。
先看看 RegexMatch 函数:正则表达式调出 wrote:模式匹配是继续进行或失败,取决于调出函数的返回值:
- 如果函数返回 0 或没有返回数值,则匹配操作如常进行。
- 如果函数返回 1 或更大的数字,则在当前位置匹配失败,但继续进行剩余部分的匹配测试。
Code: Select all
Haystack = Whoa, the quick brown fox jumps over the lazy dog.
FoundPos := RegExMatch(Haystack, "(the) (\w+)\b(?CCallout)")
Callout(m) {
MsgBox m=%m%[c]nm1=%m1%[/c]nm2=%m2%
return 0
}
现在到 RegexReplace 函数:
Code: Select all
Haystack = Whoa, the quick brown fox jumps over the lazy dog.
NewText := RegExReplace(Haystack, "(the) (\w+)\b(?CCallout)", "the wild")
Callout(m) {
MsgBox m=%m%[c]nm1=%m1%[/c]nm2=%m2%
return 0
}
小结:调出函数返回值为 0 时匹配操作如常进行,但对于这两个函数是不一样的。此时,RegexMatch 匹配成功并返回,而 RegexReplace 则进行本次替换并继续往后搜索。而返回值为 1 时,则 RegexMatch 匹配失败并继续往后搜索,RegexReplace 则不进行本次替换并继续往后搜索。尽管还有其他返回值,等大家自行探索啦!
异想天会开吗?
这个例子改自 ahk8.com 一个问题的答案:
Code: Select all
Text =
(
1 Lesser Heal
2 Fen Creeper
2 Holy Nova
1 Mind Control
)
CardList := {"Lesser Heal":"次级治疗术","Fen Creeper":"沼泽爬行者","Holy Nova":"神圣新星","Mind Control":"精神控制"}
NewText := RegExReplace(Text,"`amO)^([12] )(.+)$(?CCallout)", r)
MsgBox % NewText
Return
Callout(o){
global CardList, r
r := o[1] . CardList[o[2]] "`n"
return 0
}
要获取替换后的字符串却是可行的,只需把 Callout() 函数中赋值 r 的语句替换,这时替换后的字符串会保存在变量 r 中了(不是 NewText):
Code: Select all
r .= o[1] . CardList[o[2]] "`n"
通过调出功能揭示了正则表达式的内部匹配机制,可帮助找出匹配不成功的问题点(在怀疑处前后都进行调出,若之前匹配而之后没有则找到问题了),对于解决正则表达式的问题有直接的帮助。当然,只要你喜欢,可以在一个模式中多次使用调出语法,让这个黑箱子四处透光,不用担心有人会找你麻烦。