热字串和自动替换

入门和简单示例

尽管热字串主要用于在您输入缩写时进行扩展 (自动替换), 但是它们也可以用来运行任何脚本动作. 从这个角度看, 它们类似于 热键, 只是它们通常由多个字符组成 (即字符串).

要定义热字串, 请用两个双冒号包围用来触发的缩写, 例如:

::btw::by the way

在上面的例子中, 每当您输入缩写 btw 时会被自动替换为 "by the way" (不过, 默认情况下您必须在输入 btw 后输入 终止符, 例如空格, 句点或回车).

上面的 "by the way" 示例被称为自动替换热字串, 因为输入的文本被自动替换为第二个双冒号后指定的字符串. 与之相比, 热字串还可以定义用来执行任何自定义动作, 例如. 注意命令必须放在热字串的 下面.

::btw::
MsgBox You typed "btw".
return

:*:]d::  ; 此热字串通过后面的命令把 "]d" 替换成当前日期和时间.
FormatTime, CurrentDateTime,, M/d/yyyy h:mm tt  ; 看起来会像 9/1/2005 3:53 PM 这样
SendInput %CurrentDateTime%
return

尽管上面的两个例子不是自动替换的热字串, 但默认情况下您输入的缩写也会被擦除. 这是通过自动退格来实现的, 此特性可以通过 b0 选项 禁用.

终止符

除非使用了 星号选项, 否则您必须在热字串的缩写后输入 终止符 才能触发它. 开始时终止符包含下列字符:-()[]{}':;"/\,.?!`n `t(注意 `n 是回车,`t 是 Tab,且在它们之间还有一个原义的空格)。通过编辑下列示例可以改变这个字符集合,这个例子中为 所有的 热字串设置新的终止符,而不仅是在它下面的那些。

#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t

选项

可以使用下面的两种方式改变热字串的默认行为:

  1. #Hotstring 指令, 它会影响脚本中实际在它后面的所有热字串. 下列示例会让 C 和 R 选项生效:#Hotstring c r
  2. 把选项放在热字串的第一个双冒号之间. 下列示例会让 C 和 * 选项对当前热字串生效:
    :c*:j@::john@somedomain.com ; 区分大小写且“不需要终止符”。

下面列表中对每个选项进行说明. 当使用上面的方法指定多个选项时, 可以在选项间包含空格.

* (星号): 不需要终止符 (即空格, 句点或回车) 来触发热字串. 例如:

:*:j@::jsmith@somedomain.com

上面的示例会在您输入 @ 字符时立即进行替换. 如果在 #Hotstring 指令 中含有此选项, 那么可以使用 *0 来关闭它.

? (问号): 即使此热字串在另一个单词中也会被触发; 即, 在字符串被混排前立即输入字符. 例如,如果 :?:al::airline 为热字串,那么输入“practical ”会得到“practicairline ”。使用 ?0 来关闭此选项.

B0 (B 后跟着零): 进行自动退格来擦除您输入的缩写. 关闭此选项后可以使用 B 来启用. 脚本还可以通过 {bs 5} 实现自己的退格, 这里发送 5 次退格. 同样地, 可以通过 {left 5} 发送左方向键的键击. 例如,下面的热字串产生“<em></em>”并把光标向左移动 5 个位置(这样它就在标签之间了):

:*b0:<em>::</em>{left 5}

C: 区分大小写: 当您输入缩写时, 它必须准确匹配脚本中定义的大小写形式. 使用 C0 可以关闭区分大小写的特性.

C1: 不遵循输入的大小写形式. 使用此选项可以让 自动替换热字串 不区分大小写且阻止它们遵循您实际输入字符的大小写形式. 遵循大小写形式的热字串 (这是默认状态) 会在您输入的缩写都为大写时产生大写形式的的替换文本. 如果您的输入只有首字母为大写,那么替换的首字母也会为标题格式(如果首个字符是字母)。您按其他任何大小写形式输入时, 替换会准确按照定义进行发送. 如果在 #Hotstring 指令 中含有此选项, 那么可以使用 C0 来关闭它, 这样可以让热字串重新遵循大小写.

Kn: 按键延迟: 这个非常少用的选项设置在自动退格或 自动替换 产生的键击之间的延迟. 给 n 指定新的延迟; 例如, 指定 k10 来设置 10ms 的延迟而 k-1 则取消延迟. 此选项的实际效果取决于当前生效的 发送模式:

O: 进行替换时忽略 自动替换热字串 的终止符. 它可以用于当您希望使用终止符让热字串保持清晰, 却不希望终止符显示在屏幕上的时候. 例如,如果 :o:ar::aristocrat 为热字串,那么输入“ar”后跟着空格键会产生不含尾随空格的“aristocrat”,这样可以让您在不需要退格的情况下补上单词的复数或所有格形式。使用 O0 (字母 O 后跟着零) 来关闭此选项.

Pn: 字符串的 优先级 (例如 P1). 这个非常少用的选项对 自动替换热字串 没有效果.

R: 发送原始的替换文本; 即准确地按照原样发送, 而不把 {Enter} 转换成 ENTER 键击, 把 ^c 转换成 Control-C, 等等. 此选项在含 延续片段 热字串中自动生效. 使用 R0 来关闭此选项.

SISPSE [v1.0.43+]:设置自动替换热字串发送键击的方法。这些选项是互相排斥的: 每次只会有一个生效. 下面对每个选项进行说明:

如果未使用上面的任何一个选项, 则在 v1.0.43 及更高的版本中默认模式为 SendInput. 然而, 与 SI 选项不同的是, 在 SendInput 不可用时会使用 SendEvent 而不是 SendPlay.

Z: 这个非常少用的选项会在每次热字串触发后重置热字串识别器. 换句话说, 脚本将开始等待全新的热字串, 而不考虑您之前输入的任何内容. 这可以避免意外地触发字符串. 为了进行说明, 请思考下面的字符串:

:b0*?:11::
SendInput xx
return

由于上面没有使用 Z 选项, 所以输入 111 (三个连续的 1) 会触发热字串两次, 因为中间的 1 既是首次触发的 末尾 字符, 又是第二次触发的 起始 字符. 在 b0 前面加上字母 Z 后, 您必须输入四个 1 而不是三个才能触发热键两次. 使用 Z0 来关闭此选项.

超长替换

使用 延续片段 的方法可以让产生大量替换文本的热字串变得更具可读性和可维护性. 例如:

::text1::
(
Any text between the top and bottom parentheses is treated literally, including commas and percent signs.
By default, the hard carriage return (Enter) between the previous line and this one is also preserved.
    By default, the indentation (tab) to the left of this line is preserved.

See continuation section for how to change these default behaviors.
)

使用延续片段后也会使热字串默认为 原始模式. 覆盖此特性的唯一方法是在每个含延续片段的热字串中指定 r0 选项(例如 :r0:text1::)。

上下文相关的热字串

使用 #IfWinActive/Exist 指令可以让选择的热字串产生上下文相关性. 这样的热字串会根据窗口是否活动或存在的不同情况发送不同的替换, 执行不同的动作或什么都不做. 例如:

#IfWinActive ahk_class Notepad
::btw::This replacement text will appear only in Notepad.
#IfWinActive
::btw::This replacement text appears in windows other than Notepad.

自动更正

后面的脚本使用热字串即时更正大约 4700 常见的英文拼写错误. 它还包含了 Win+H 热键来方便地添加更多拼写错误:

下载: AutoCorrect.ahk (127 KB)

作者: Jim Biancolo维基百科的常见拼写错误列表

备注

替换文本中当前不支持例如 %MyVar% 这样的变量引用。要解决此问题,请不要让这样的热字串自动替换。而是在缩写的下面使用 SendInput 命令,后跟着仅包含单词 Return 的行。

要在替换文本后发送额外的空格或 tab, 可以把它们加在替换文本后, 但需要在末尾加上重音符/反引号 (`). 例如:

:*:btw::By the way `

鼠标左键或右键的任何点击都会重置热字串识别器. 换句话说,脚本将开始等待全新的热字串,而不考虑您之前输入的任何内容(如果您不希望这样,请在脚本的任意位置指定 #Hotstring NoMouse 这行)。在 "鼠标点击时重置" 的行为是默认的, 因为每次点击通常会移动插入点 (光标) 或设置键盘焦点到新的控件/区域. 在这种情况下, 通常希望: 1) 即使没有 问号选项 也触发热键; 2) 防止您在点击鼠标后输入的一些内容与之前输入的内容意外形成有效的缩写从而触发热字串.

内置变量 A_EndChar 包含了触发最近的非自动替换热字串时的终止符. 如果不需要终止符 (使用了 * 选项), 那么它会被置空. A_EndChar 可以用于使用 Send 命令的热字串或根据您输入的不同终止符改变行为的那些热字串。要发送终止符自身,请使用 SendRaw %A_EndChar%(使用 SendRaw 是因为普通的 Send 命令无法正确发送类似 !{} 这样的字符)。

尽管在热字串定义中的逗号、百分号和单冒号不需要进行转义,但反引号和那些在空格或 tab 右边的分号则需要。请参阅 转义序列 了解完整的列表.

尽管在 自动替换文本 (在没有使用 原始选项 时) 中支持 Send 命令 的特殊字符例如 {Enter}, 但热字串自身却不使用这种方式. 而是使用 `n 表示 ENTER 键, `t (或原义的 tab) 表示 TAB (请参阅 转义序列 了解完整的列表). 例如,当您输入“ab”后跟着 tab 时会触发热字串 :*:ab`t::

热字串会原义地处理在它的定义中的空格和 tab。例如后面的热字串会产生两种不同的效果:::btw::by the way::btw:: by the way

每个热字串缩写的长度不能超过 40 个字符. 超出此长度后程序会向您提出警告. 与之相比, 当 发送模式 为默认的 SendInput 时热字串的替换文本的长度限制约为 5000 个字符. 通过切换到其他 发送模式 可以把此限制增加到 16,383 字符. 此外,在热字串的替换文本部分使用 SendPlay %MyVariable% 可以发送不限数量的文本。

热字串的定义顺序决定了它们的相对优先级. 换句话说, 如果多个热字串匹配您输入的内容, 那么只有脚本中首先列出的那个会生效. 相关主题:上下文相关热字串

为了识别热字串, 您输入的所有退格都会被计算进来. 然而, 使用方向键, PageUp, PageDown, Home 以及 End 在编辑器中导航会重置热字串识别过程. 换句话说, 它会开始等待全新的热字串.

即使当前活动窗口忽略您的键击时也可以输入热字串. 换句话说, 即使触发的缩略词不可见时热字串仍会被触发. 此外, 您还可以使用退格键撤销最近输入的键击 (尽管您无法看到效果).

可以 GosubGoto 到热字串标签, 只需在热字串的标签名称前包含第一个双冒号 (以及所有选项符号). 例如:Gosub ::xyz。然而, 跳转到 单行 (自动替换) 热字串 会除了执行 return 外什么都不做.

尽管不会监视热字串且在不可见的 Input 命令执行时也不会触发它们, 但是可见的 Input 却能触发它们.

默认情况下, 由任何 AutoHotkey 脚本生成的键击永远不会触发热字串. 这避免了热字串彼此反复地触发而形成的无限循环的可能性. 在 v1.1.06 及更高版本中, 此行为可以使用 #InputLevelSendLevel 进行控制. 然而, 自动替换型热字串的发送级别总为 0, 因此永远不会触发 钩子热键 或热字串.

在某些时候 Input 命令比热字串更灵活. 例如, 它可以对活动窗口 (例如游戏) 隐藏您的键击. 它还支持非字符型的终止键, 例如 Escape.

任何包含热字串的脚本会自动使用 键盘钩子.

在下面的情况中热字串与热键具有相同的特性:

已知限制: 在 Java 应用程序的某些系统中, 热字串可能会干扰用户输入 diacritical 字母 (通过 dead 键). 为了解决此问题, 可以临时打开 Suspend (这样禁用了所有热字串).

热字串助手

Andreas Borutta 推荐了下面的脚本, 如果您是深度的热字串用户, 那么它会很有用. 使用 Win+H (或您选择的其他热键), 可以把当前选择的文本转变成热字串. 例如, 如果您在字处理软件中选择了 "by the way", 按下 Win+H 会提示您输入其缩写 (例如 btw), 然后把新热字串添加到脚本中. 之后会重新载入脚本来激活热字串.

#h::  ; Win+H hotkey
; 获取当前选择的文本. 使用剪贴板代替
; "ControlGet Selected", 是因为它可以工作于更大范围的编辑器
; (即字处理软件).  保存剪贴板当前的内容
; 以便在后面恢复. 尽管这里只能处理纯文本,
; 但总比没有好:
AutoTrim Off  ; 保留剪贴板中任何前导和尾随空白字符.
ClipboardOld = %ClipboardAll%
Clipboard =  ; 必须清空, 才能检测是否有效.
Send ^c
ClipWait 1
if ErrorLevel  ; ClipWait 超时.
    return
; 替换 CRLF 和/或 LF 为 `n 以便用于 "发送原始模式的" 热字串:
; 对其他任何在原始模式下可能出现问题
; 的字符进行相同的处理:
StringReplace, Hotstring, Clipboard, ``, ````, All  ; 首先进行此替换以避免和后面的操作冲突.
StringReplace, Hotstring, Hotstring, `r`n, ``r, All  ; 在 MS Word 等软件中中使用 `r 会比 `n 工作的更好.
StringReplace, Hotstring, Hotstring, `n, ``r, All
StringReplace, Hotstring, Hotstring, %A_Tab%, ``t, All
StringReplace, Hotstring, Hotstring, `;, ```;, All
Clipboard = %ClipboardOld%  ; 恢复剪贴板之前的内容.
; 这里会移动 InputBox 的光标到更人性化的位置:
SetTimer, MoveCaret, 10
; 显示 InputBox, 提供默认的热字串:
InputBox, Hotstring, New Hotstring, Type your abreviation at the indicated insertion point. You can also edit the replacement text if you wish.`n`nExample entry: :R:btw`::by the way,,,,,,,, :R:`::%Hotstring%
if ErrorLevel  ; 用户选择了取消.
    return
IfInString, Hotstring, :R`:::
{
    MsgBox You didn't provide an abbreviation. The hotstring has not been added.
    return
}
; 否则添加热字串并重新加载脚本:
FileAppend, `n%Hotstring%, %A_ScriptFullPath%  ; 在开始处放置 `n 以防文件末尾没有空行.
Reload
Sleep 200 ; 如果加载成功, reload 会在 Sleep 期间关闭当前实例, 所以永远不会执行到下面的语句.
MsgBox, 4,, The hotstring just added appears to be improperly formatted.  Would you like to open the script for editing? Note that the bad hotstring is at the bottom of the script.
IfMsgBox, Yes, Edit
return

MoveCaret:
IfWinNotActive, New Hotstring
    return
; 否则移动 InputBox 中的光标到用户输入缩写的位置.
Send {Home}{Right 3}
SetTimer, MoveCaret, Off
return