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

NSIS版本字符串校验脚本问题求助:现有条件判断失效

NSIS版本字符串校验脚本问题修复

校验需求说明

合法格式示例

  • 3.3、3.42、23.5、23.56w、3.467、999.999、999.99a

不合法格式示例

  • 1.b(长度不足3)、8..a(包含多个句点)

核心校验规则

  1. 版本字符串非空
  2. 长度至少3个字符
  3. 必须包含且仅包含一个英文句点(.)
  4. 句点前的所有字符均为数字
  5. 句点后到倒数第二个字符(若存在)均为数字
  6. 最后一个字符为数字或大小写字母

原脚本存在的问题

  1. 索引逻辑错误:取最后一个字符时,使用总长度作为索引(NSIS字符串索引从0开始,最后一位索引应为总长度-1),导致无法正确获取目标字符。
  2. 条件判断混乱:最后一个字符的合法性判断中,${AndIf}与${OrIf}混用,逻辑不符合预期,会错误拦截合法字符。
  3. 校验范围缺失:仅校验句点前的字符,未处理句点后到倒数第二个字符的校验,也未限制句点数量,无法拦截8..a这类非法格式。
  4. 提示信息错误:检测不到句点时提示“Version must contain a digit”,与实际校验要求不符。
  5. 循环终止逻辑错误:循环仅到句点位置就终止,未处理后续字符的校验流程。

修复后的完整脚本

!include "StrFunc.nsh"
${StrCount}
${StrFind}

Function ValidateVersion
    Exch $sVersion
    Push $R0 $R1 $R2 $R3 $R4 $R5

    ; 规则1:非空校验
    ${If} $sVersion == ""
        MessageBox MB_OK "版本不能为空"
        Pop $R5 $R4 $R3 $R2 $R1 $R0
        Abort
    ${EndIf}

    StrCpy $R1 $sVersion
    Strlen $R2 $R1

    ; 规则2:长度至少3位
    ${If} $R2 < 3
        MessageBox MB_OK "版本长度至少3位(需包含句点)"
        Pop $R5 $R4 $R3 $R2 $R1 $R0
        Abort
    ${EndIf}

    ; 规则3:检查是否包含且仅包含一个句点
    ${StrCount} $R0 $R1 "."
    ${If} $R0 != 1
        MessageBox MB_OK "版本必须包含且仅包含一个句点(.)"
        Pop $R5 $R4 $R3 $R2 $R1 $R0
        Abort
    ${EndIf}

    ; 获取句点的索引位置
    ${StrFind} $R0 $R1 "."

    ; 规则4:校验句点前的所有字符都是数字
    StrCpy $R3 0
    loop_pre_dot:
        StrCpy $R4 $R1 1 $R3
        ${If} $R4 < "0" ${OrIf} $R4 > "9"
            MessageBox MB_OK "句点前的字符必须全为数字"
            Pop $R5 $R4 $R3 $R2 $R1 $R0
            Abort
        ${EndIf}
        IntOp $R3 $R3 + 1
        StrCmp $R3 $R0 loop_pre_dot

    ; 规则5:校验句点后到倒数第二个字符(若存在)都是数字
    IntOp $R3 $R0 + 1
    IntOp $R4 $R2 - 1
    ${If} $R3 < $R4
        loop_between_dot_last:
            StrCpy $R5 $R1 1 $R3
            ${If} $R5 < "0" ${OrIf} $R5 > "9"
                MessageBox MB_OK "句点后到倒数第二个字符必须全为数字"
                Pop $R5 $R4 $R3 $R2 $R1 $R0
                Abort
            ${EndIf}
            IntOp $R3 $R3 + 1
            StrCmp $R3 $R4 loop_between_dot_last
    ${EndIf}

    ; 规则6:校验最后一个字符是数字或字母
    StrCpy $R5 $R1 1 $R4
    ${If} $R5 < "0" ${OrIf} $R5 > "9"
        ${If} $R5 < "A" ${OrIf} $R5 > "Z"
            ${If} $R5 < "a" ${OrIf} $R5 > "z"
                MessageBox MB_OK "最后一个字符必须是数字或大小写字母"
                Pop $R5 $R4 $R3 $R2 $R1 $R0
                Abort
            ${EndIf}
        ${EndIf}
    ${EndIf}

    Pop $R5 $R4 $R3 $R2 $R1 $R0
FunctionEnd

修复说明

  • 引入StrFunc插件的${StrCount}和${StrFind},确保版本仅含一个句点,拦截多句点非法格式。
  • 修正最后一个字符的索引计算逻辑,用总长度-1正确获取目标字符。
  • 拆分最后一个字符的判断逻辑,避免逻辑运算符混用导致的错误拦截。
  • 新增句点后到倒数第二个字符的校验流程,覆盖所有规则要求。
  • 修正提示信息,使其准确对应校验规则。
  • 调整循环终止条件,确保每段字符都被完整校验。

内容的提问来源于stack exchange,提问作者Kanaparthi Jaya Krishna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:35:34