具有动态热字符串模块的自动热键变量分配

问题描述

我已经指向this AutoHotKey模块,该模块允许动态字符串。

其中一个示例是键入时计算百分比(例如5/40%将变为8%)。为此,以下代码是必需的:

hotstrings("(\d+)\/(\d+)%","percent")

percent:
p := Round($1 / $2 * 100)
Send,%p%`%
Return

我想使用此模块将单词内的中间点.替换点。我已经找到了如何“查找”文本,但是没有正确地替换它。我需要引用初始文本才能将其放入替换文本中。在上面的代码中,使用p := Round($1 / $2 * 100)使用输入的数字来计算百分比,但是我不知道如何对字母进行同样的操作。

我的代码如下:

hotstrings("[a-z]\.[a-z](\.[a-z])*","word")

word:
a := $1
b := $2
Send,a{U+22C5}b
Return

但是,这只是用一个间的点替换了整个内容,而不是替换了周围的字母。另外,我也不知道如何考虑多个点的可能性(例如a.b.c.d)。在python中,我会做一个for循环,但是我真的不知道AutoHotKey。

我该怎么做?

谢谢

解决方法

这里没有什么问题。

第一个是正则表达式。
首先,您并不是真的想将正则表达式视为与无限长的字符串a.b.c.d.e.f.g.h.i.j.k.l....匹配,而是只想考虑单个情况x.y。这些案例可以彼此相邻。
因此,请摆脱(\.[a-z])*

第二,您没有捕获组。或者,您确实有一个,但是我假设您不小心这样做了。如果您还不熟悉Regex捕获组,我建议您学习它们,它们在某些情况下非常有用(例如此处!)。
但是无论如何,要创建捕获组,只需将( )放在要捕获的正则表达式部分即可。
因此,您想捕获.之前和之后的字符(或者,实际上,仅捕获后者的字符,这种方法会有问题,以后会更多)。所以您的Regex现在看起来像这样:
([a-z])\.([a-z])
匹配后,hotstrings()函数将输出两个变量$1$2(就是它们,变量名)。
当您引用变量时,$1为您提供.之前的字符,而$2为您提供.之后的字符。


所以现在我们进入第二个问题,即捕获组变量。

a := $1
b := $2
Send,a{U+22C5}b

在这里您无缘无故地创建变量ab,尽管这当然不是问题,但是您如何尝试引用变量a和{{1} }是一个问题。
您使用的是send命令,因此使用的是旧版AHK语法。在旧版AHK语法中,您通过将变量包装在b中来引用变量。
因此,您的send命令将如下所示:
%%
但是不要写旧版AHK(即使Send,%a%{U+22C5}%b%函数完全是旧版AHK)。
要切换到现代AHK(表达式语法),我们需要指定一个hotstrings(),后跟一个空格。然后我们可以这样做:
%
还跳过了定义无用的变量SendInput,% $1 "{U+22C5}" $2a的操作,并由于建议使用更快,更可靠的发送模式而切换了SendInput


现在将有一个几乎可以正常工作的脚本,如下所示:

b

这将存在链接多个hotstrings("([a-z])\.([a-z])","word") return word: SendInput,% $1 "{U+22C5}" $2 Return 的问题。但这很好,因为Regex可以做更多的改进。

我们想在后面使用正向外观,并仅捕获a.b.c.d.e.f.g...之后的字符,如下所示:
. 另外,我想用(?<=[a-z])\.([a-z])替换[a-z](匹配任何单词字符)是合适的。因此,正则表达式和整个脚本将是:

\w

现在它应该可以按要求工作。
如果我在谈论传统AHK与现代AHK时混淆了您(如果您不知道两者之间的区别,那是可以预料的),我建议您提供这是一个读物:
https://www.autohotkey.com/docs/Language.htm