在完成了之前的一篇文章之后,又继续往下看了一下AutoIt帮助文档,于是就有了这篇文章.

本文其实是帮助文档tutorials部分的4个章节的翻译.我做了适当的省略和改写,也加上了一些自己的理解.希望能起到一个抛砖引玉的作用.如果有理解错误的地方,还望批评指正~
这四个章节,前三个是例子,第四个是对正则表达式的学习.

 
一.显示一个hello world的窗口
就一条语句
MsgBox(0, "Tutorial", "Hello World!")
函数显示一个对话框,带3个参数:flag,title和message.
flag是对话框的样式,其余两个是string类型的参数
对于string的参数要用引号(单双引号都一样)
对于flag不同的值代表不同的样式,详见帮助,例如下面的
MsgBox(1+64+256,"tutorial","helloworld")
需要不同的样式,只需要将不同的值加在一起即可

二. 运行"记事本"自动输入一些内容,然后关闭

运行记事本程序的语句
Run("notepad.exe")

然后可以用window info工具获取窗口的title,对于记事本一般是"无标题 - 记事本"
当程序启动之后,我们要等待窗口出现并称为活动的(active 注1),然后才能按键.
等待的过程可以使用WinWaitActive()函数
WinWaitActive("无标题 - 记事本")
大多数与窗口相关的函数都以窗口的title做参数

当窗口打开并且是活动的,是等待我们输入的状态(你可以看到输入光标在闪,表示当前的焦点就在那里),这个时候就可以输入文本了.可以使用Send()函数
Send("This is some text.")
你可以测试脚本运行,就会看到效果了

然后是关闭窗口,使用WinClose()函数
WinClose("无标题 - 记事本")

当关闭的时候会弹出对话框(对话框也是窗口window,注2)提示是否保存.使用info tool来得到对话框的细节
加一行语句等待这个对话框成为活动的
WinWaitActive("记事本", "文件 无标题")
(这里使用了窗口里的文本来让函数更明确的区分这个窗口与原来的记事本窗口,我们这里使用的文本是"文件 无标题")

接下来我们想要实现自动的按下Alt-N 来按动"否"的按钮
(窗口里面的字母有下划线表示是快捷键,一般加alt,所以这里用alt+Y为"是",alt+N为"否")
使用Send()函数发alt键是发"!",所以alt+n就是
Send("!n")

所以整个脚本如下
Run("notepad.exe")
WinWaitActive("无标题 - 记事本")
Send("This is some text.")
WinClose("无标题 - 记事本")
WinWaitActive("记事本", "文件 无标题")
Send("!n")

三 winzip 安装

这个例子很简单,只是过程复杂点,无非是反复的用上面的几个函数,对照文档看下即可
在此略

四 正则表达式

几乎所有的程序语言都有这个特性,这里只是简单的介绍AutoIt里面的StringRegExp()这个函数(简称SRE)
函数形式
StringRegExp( "test", "pattern" [, flag ] )
参数
"test"  用于查找的字符串
"pattern" 要查找的字符串
flag 可选,用于告诉函数你是要知道是否找到,或者返回第一个匹配的,或者返回所有匹配的结果.

首先要了解一下正则表达式的基础知识,也就是这个函数的执行过程:
pattern这个部分就是告诉函数逐个字符的对它进行检查匹配.例如检查"test",先是检查t是否匹配,只有匹配了才会检查下一个字符e.如果目的串的下一个字符是a,而不是你找的e就说明匹配失败了.如此进行下去.

例1
MsgBox(0, "SRE Example 1 Result", StringRegExp("text", 'test'))
其中StringRegExp("text", 'test')的返回值是0,表示没有找到匹配的

[]代表逻辑或,例如"[sx]"表示或者是s或者是x其中的一个
例2
MsgBox(0, "SRE Example 2 Result", StringRegExp("text", 'te[sx]t'))
MsgBox(0, "SRE Example 2 Result", StringRegExp("test", 'te[sx]t'))
结果都是1,因为都匹配

{}表示匹配的次数,也可以指定一个范围"{最小次数,最大次数}"
例3
MsgBox(0, "SRE Example 3 Result", StringRegExp("text", 't{1}e{1}[sx]{1}t{1}'))
MsgBox(0, "SRE Example 3 Result", StringRegExp("aaaabbbbcccc", 'b{4}'))

以上都是flag默认为0的情况,与StringInStr() 函数的功能大多数情况都是一样的
但是当flag的值为其他的时候,情况就不同了.例如你在玩游戏的时候会出现类似
"Gnarly Monster hits you for 18 damage." (某怪兽打了你18个伤害)
你现在想要知道你被打了多少下.当然不能匹配18.因为你也不知道你要匹配的具体字符是什么,只知道是数字而已.

 
现在要确定匹配的pattern的特点(之前的都是很明确的某个字符串,现在是未知的)
1)它只包含数字
2)有时是2个字符长
2a)最大值是999
2b)最小值是0
3)肯定是1到3个字符长
4)在目标串里面没有其他的数字
在回答这个问题前先看一个例子

例4
$asResult = StringRegExp("This is a test example", '(test)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Example 4 Result", $asResult[0])
EndIf
$asResult = StringRegExp("This is a test example", '(te)(st)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Example 4 Result", $asResult[0] & "," & $asResult[1])
EndIf
看第一句话StringRegExp("This is a test example", '(test)', 1)
这里flag的值为1,还有分组符号"()"
flag为1表示函数在做匹配成功以后,会返回一个数组,数组里的每个元素都是分组符号()里面的值
所以这个里面返回的$asResult[0]就是括号里的test
再看StringRegExp("This is a test example", '(te)(st)', 1)
同样先做匹配,确实匹配了te和st连在一起,匹配成功(做匹配类似将括号去掉)
然后开始返回数组,数组里面的第一个值$asResult[0]是第一个括号的te,第二个值$asResult[1]是第二个括号里面的st
说白了,()只是起到对返回的结果进行分割,分别放到不同的数组元素里面的作用.

然后回到打怪的问题中,对于我们感兴趣的pattern的定义写为"([0-9]{1,3})". 直接解释就是0到9之间的某个数字出现1到3次
所以可以这么写
例5
$asResult = StringRegExp("Gnarly Monster hits you for 18 damage.", _
                               '([0-9]{1,3})', 1)
If @error == 0 Then
    MsgBox(0, "SRE Example 5 Result", $asResult[0])
EndIf
其中_为代码中的换行

如果游戏中出现的是
"You deflect 36 of Gnarly Monster's 279 damage."你使279个伤害里面的36个打歪
如果你运行上面的程序,会出现36而不是需要的279.所以现在要确定的样式是数字后面还要有" damage"(空格加damage),所以是 "([0-9]{1,3} damage)",但是这样函数返回的值是"279 damage"而不是"279".如何去掉呢,要使用非捕捉组的符号(说白了就是匹配,但是不返回),符号是 "(?:xxx)"xx为要匹配的字符串.所以可以写成
例6
$asResult = StringRegExp("You deflect 36 of Gnarly Monster's 279 damage.", '([0-9]{1,3})(?: damage)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Example 6 Result", $asResult[0])
EndIf
其中'([0-9]{1,3})(?: damage)'即要匹配"前面0到3个数字"+"空格"+"damage",但是前面的数字要返回保存,后面的空格damage不返回.
如果直接的写法可以写成
'([0-9]{1,3})( damage)'
'([0-9]{1,3}) damage'
因为不管如何匹配,$asResult[0]都是放的第一个()里面的内容

总结:
说这么多只是要说一下正则表达式的运行的理论基础.记住:
1 是逐个字符匹配的
2 [..]表示匹配括号里面的其中一个
3 看看SRE这个函数的帮助,特别是Repeating Characters"这一节.这可以使你的代码易读.例如"*"与{0,} 一样,代表0到任意个字符.


 
注1:
active也是windows的基本原理之一,也就是当前活动的窗口.一般也就是正在操作的窗口,高亮显示(也就是标题是亮蓝色的)
注2:
窗口是windows操作系统的基本元素
注3:
还有一篇入门文章推荐阅读