You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AutoIt中实现仅支持?和*通配符的高效字符串模式匹配函数(禁用正则表达式)

如何在AutoIt中实现仅支持?和*通配符的高效字符串模式匹配函数(禁用正则表达式)

我完全懂你的需求痛点:你需要一个只识别?(匹配任意单个字符)和*(匹配任意长度字符,包括空内容)的通配符匹配工具,但用正则表达式的话,模式里的其他特殊字符(比如.、+)会被当成正则语法解析,完全不符合你的预期;而且你要处理大量比较,所以效率必须跟上。

先说说你原来代码的问题:StringRegExp会把模式里的非通配符特殊字符当成正则元字符处理,比如如果你的模式是a.b,正则会把.解析成“任意单个字符”,但你其实只想匹配字面量a.b,这就会导致错误匹配。

下面是一个基于双指针迭代的高效实现,完全避开正则,只处理?和*两个通配符,同时支持大小写敏感开关:

Func iswm($string, $pattern, $caseSensitive = 1)
    ; 处理大小写不敏感的情况
    If Not $caseSensitive Then
        $string = StringLower($string)
        $pattern = StringLower($pattern)
    EndIf

    Local $sLen = StringLen($string)
    Local $pLen = StringLen($pattern)
    Local $sPtr = 1 ; 字符串遍历指针
    Local $pPtr = 1 ; 模式遍历指针
    Local $starPos = -1 ; 记录最近一次遇到*的位置
    Local $matchPos = 0 ; 记录*对应的字符串匹配起始位置

    While $sPtr <= $sLen
        ; 情况1:当前模式字符是?,或与字符串字符完全匹配,同时前进两个指针
        If $pPtr <= $pLen And (StringMid($pattern, $pPtr, 1) = "?" Or StringMid($pattern, $pPtr, 1) = StringMid($string, $sPtr, 1)) Then
            $sPtr += 1
            $pPtr += 1
        ; 情况2:当前模式字符是*,记录位置后只前进模式指针
        ElseIf $pPtr <= $pLen And StringMid($pattern, $pPtr, 1) = "*" Then
            $starPos = $pPtr
            $matchPos = $sPtr
            $pPtr += 1
        ; 情况3:之前遇到过*,回溯到*的下一个位置,尝试让*匹配更多字符
        ElseIf $starPos <> -1 Then
            $pPtr = $starPos + 1
            $matchPos += 1
            $sPtr = $matchPos
        ; 情况4:没有匹配上,也没有*可以回溯,直接返回不匹配
        Else
            Return 0
        EndIf
    Wend

    ; 处理模式末尾剩余的*(比如模式是"abc*",字符串是"abc",应该匹配)
    While $pPtr <= $pLen And StringMid($pattern, $pPtr, 1) = "*"
        $pPtr += 1
    Wend

    ; 如果模式指针走完了整个模式,说明完全匹配
    Return $pPtr > $pLen ? 1 : 0
EndFunc

测试你的示例场景:

ConsoleWrite(iswm("hello whale", "?ello *", 1) & @CRLF) ; 输出1,匹配成功
ConsoleWrite(iswm("hello whale", "?ello w?al*", 1) & @CRLF) ; 输出1,匹配成功

额外测试场景(验证特殊字符不被错误解析):

; 模式里的.是普通字符,只有?是通配符
ConsoleWrite(iswm("a.b", "a?b", 1) & @CRLF) ; 输出1(?匹配.)
ConsoleWrite(iswm("aab", "a.b", 1) & @CRLF) ; 输出0(.是普通字符,和a不匹配)
; *匹配任意长度字符,大小写不敏感
ConsoleWrite(iswm("TEST123ABC", "test*abc", 0) & @CRLF) ; 输出1,匹配成功

这个算法的核心优势:

  • 无正则干扰:完全自定义处理?和*,其他所有字符都按字面量匹配,不会出现意外解析
  • 高效:线性时间复杂度O(n+m),n是字符串长度,m是模式长度,适合大规模批量比较
  • 鲁棒性:处理了各种边界情况,比如模式开头/结尾是*、多个连续*、空字符串匹配等

备注:内容来源于stack exchange,提问作者user24511835

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 15:39:50