字符串处理在多数编程语言中都是重头戏,AHK 自然也不例外。AHK 在字符串处理方面还是很灵活的,如果掌握好了,写起代码来会事半功倍。本文先介绍最常用的操作:拼接和遍历。
字符串拼接
拼接恐怕是最常用的操作了,在 AHK 中也非常简单,直接将两个字符串用空格隔开就可以了。
a := "abc"
b := 100
c := "def"
d := 123.456
e := 200
; f 的值是字符串 abc100anddef123.456
f := a b "and" c d
; g 的值是字符串 100200
g := b e
不管是字符串、整数还是浮点数,都可以用空格拼接成一个字符串。更神奇的是,空格可以和其他算术运算符一起使用。
a := 100
b := 200
; c 的值是 100150
c := a b - 50
其实 AHK 中整数 100200 和 字符串 "100200" 是没有区别的,当整数用的时候就是 100200,当字符串用的时候就是 "100200",当然内部实现上会有一些优化。如果感觉无法接受的话,也可以认为整数和字符串是有区别的,在实际使用中会自动相互转换。
实际上,AHK 中 .(点运算符)是专门用来拼接字符串的,在某些情况还是不能省略的。
a := 300
b := 200
; c 的值是 100
c := a - b
; d 的值是 300-200
d := a . - b
正因为空格可以和其他算术运算符一起使用,使用起来可以很灵活,为了避免歧义,空格只有在必要的情况(即这个表达式没有其他的解释办法时)才起拼接作用。
子字符串遍历
还有一个非常常见的操作,是遍历一个字符串的子字符串。Loop, Parse 是专门用来做这个的。
Loop, Parse, InputVar [, Delimiters, OmitChars]
其中 InputVar 是变量名,不需要加 %。Delimiters 是分隔符,OmitChars 是要忽略的字符。
最简单的场景就是遍历字符串中的每一个字符。
text := "abcd"
Loop, Parse, text
{
; 依次弹出
; a
; b
; c
; d
MsgBox, %A_LoopField%
}
Delimiters 和 OmitChars 都省略的情况,就是遍历字符串中的每一个字符。
另外一个典型场景是依次处理一段文字的每一行。
text =
(
line1
line2
line3
)
Loop, Parse, text, `n, `r
{
; 依次弹出
; line1
; line2
; line3
MsgBox, %A_LoopField%
}
这里 Delimiters 是 `n。`r 又是什么呢?在类 UNIX 操作系统中,文本中的换行符就是 `n,但在 Windows 中,换行符是 `r`n。如果处理一段换行符是 `r`n 的文本,直接用 `n 分隔,会保留多余的 `r,所以设置 OmitChars 为 `r 可以将其去掉。可能有不仔细的朋友认为 Loop, Parse, text, \
n, `r是将字符串同时按 \
n 和 `r 来分隔,这是错误的,`n 和 `r 的顺序也不能颠倒。
除了按换行符,我们也经常需要按其他符号分隔字符串,比如按空格,按逗号等,就大同小异了。但需要注意空格和逗号有点特殊,因为它们是特殊符号,写法有一些特别。
text := "a b,c d:xxx"
Loop, Parse, text, %A_Space%
{
; 依次弹出
; a
; b,c
; d:xxx
MsgBox, %A_LoopField%
}
Loop, Parse, text, `,
{
; 依次弹出
; a b
; c d:xxx
MsgBox, %A_LoopField%
}
Loop, Parse, text, :
{
; 依次弹出
; a b,c d
; xxx
MsgBox, %A_LoopField%
}
这里空格用的是 %A_Space%,A_Space 是一个 AHK 的内部变量,这样需要用 % 取该变量的值。`, 是用转义的方法取到的逗号字符,因为直接写逗号会被认为是参数的分隔符。类似的还有 `t 或者 %A_Tab% 是 Tab 等等,如果一个字符直接写会报语法错误,那么通常在前边加个 ` 就可以了。以后我也会专门写文章介绍转义字符。至于冒号,就没有什么特别,直接写就可以了。
有些情况我们需要按字符串分隔,而不是按字符分隔,比如:
text := "abc()bcd(cde"
需要按 () 分隔 text。需要注意,这种情况这样的写法就是错误的了:
text := "abc()bcd(cde"
Loop, Parse, text, (, )
{
; 依次弹出
; abc
; bcd
; cde
MsgBox, %A_LoopField%
}
一个可行的办法,是先将字符串中的 () 替换成一个字符串里没有的特殊字符,比如 @,然后再用这个特殊字符作为分隔符:
text := "abc()bcd(cde"
; StrReplace 函数是用来替换字符串的,我们以后再详细了解
text := StrReplace(text, "()", "@")
Loop, Parse, text, @
{
; 依次弹出
; abc
; bcd(cde
MsgBox, %A_LoopField%
}
更多内容
除了拼接和遍历字符串,我们还需要进行查找、替换、匹配、分隔、计算长度等操作,这涉及数量较多的字符串处理函数,以后我们再详细了解。
付费解决 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等领域相关问题,灵活定价,欢迎咨询,微信 ly50247。