标签 正则表达式 下的文章

hi,大家好!

为什么还不春节,最近又不知道在忙些啥,又半个月过去了,答应大家的框架,又又又跳票了!既然这样的话,今天那就再给大家分享点干货!今天的代码量比较大,大家给个一键三连吧,谢谢大家啦啦啦!
平时,我们在开发的过程中,遇到需要验证的文本框,是不是还在用IF ……Then MsgBox…… 这样的方式输出?那也太Low了,那今天就给大家分享一个完整的验证方案!来吧,让我们Hi起来!

现代 Web 开发(如 Bootstrap、Vue 等框架)通过 DOM 操作实现了“所见即所得”的验证反馈(红框、图标、气泡提示)。本文旨在通过 VBA 模拟这一机制。

1。创建类模块

首先,我们先创建一个类模块:ClsFieldValidator,你没有看错,我们上来就要创建一个类模块,这里写了几个常用的验证,必填、邮箱、手机号、身份证号、纯数字、长度限制、数值范围、自定义正则、日期格式。

' 类模块: ClsFieldValidator
Option Compare Database
Option Explicit

' 验证结果枚举
Public Enum ValidationResult
    vrValid = 0
    vrInvalid = 1
    vrEmpty = 2
End Enum

' 验证类型枚举
Public Enum validationType
    vtRequired = 1          ' 必填
    vtEmail = 2             ' 邮箱
    vtMobile = 3            ' 手机号
    vtIDCard = 4            ' 身份证号
    vtNumeric = 5           ' 纯数字
    vtLength = 6            ' 长度限制
    vtRange = 7             ' 数值范围
    vtCustomRegex = 8       ' 自定义正则
    vtDate = 9              ' 日期格式
End Enum

Private m_MinLength As Long
Private m_MaxLength As Long
Private m_MinValue As Double
Private m_MaxValue As Double
Private m_CustomPattern As String
Private m_ErrorMessage As String

' ========== 属性 ==========
Public Property Get errorMessage() As String
    errorMessage = m_ErrorMessage
End Property

Public Property Let MinLength(value As Long)
    m_MinLength = value
End Property

Public Property Let MaxLength(value As Long)
    m_MaxLength = value
End Property

Public Property Let MinValue(value As Double)
    m_MinValue = value
End Property

Public Property Let MaxValue(value As Double)
    m_MaxValue = value
End Property

Public Property Let CustomPattern(value As String)
    m_CustomPattern = value
End Property

' ========== 核心验证方法 ==========
Public Function Validate(ByVal inputValue As Variant, ByVal validationType As validationType) As ValidationResult
    Dim strValue As String
    strValue = Nz(inputValue, "")
    
    ' 清空上次错误信息
    m_ErrorMessage = ""
    
    Select Case validationType
        Case vtRequired
            Validate = ValidateRequired(strValue)
            
        Case vtEmail
            Validate = ValidateEmail(strValue)
            
        Case vtMobile
            Validate = ValidateMobile(strValue)
            
        Case vtIDCard
            Validate = ValidateIDCard(strValue)
            
        Case vtNumeric
            Validate = ValidateNumeric(strValue)
            
        Case vtLength
            Validate = ValidateLength(strValue)
            
        Case vtRange
            Validate = ValidateRange(strValue)
            
        Case vtCustomRegex
            Validate = ValidateRegex(strValue)
            
        Case vtDate
            Validate = ValidateDate(strValue)
            
        Case Else
            Validate = vrValid
    End Select
End Function

' ========== 具体验证规则 ==========

' 必填验证
Private Function ValidateRequired(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        m_ErrorMessage = "此字段为必填项"
        ValidateRequired = vrEmpty
    Else
        ValidateRequired = vrValid
    End If
End Function

' 邮箱验证
Private Function ValidateEmail(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateEmail = vrEmpty
        Exit Function
    End If
    
    ' 使用 VBScript.RegExp 进行正则验证
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    
    With regex
        .Global = True
        .IgnoreCase = True
        .Pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    End With
    
    If regex.test(strValue) Then
        ValidateEmail = vrValid
    Else
        m_ErrorMessage = "请输入有效的邮箱地址"
        ValidateEmail = vrInvalid
    End If
    
    Set regex = Nothing
End Function

' 手机号验证 (中国大陆11位手机号)
Private Function ValidateMobile(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateMobile = vrEmpty
        Exit Function
    End If
    
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    
    With regex
        .Global = True
        .Pattern = "^1[3-9]\d{9}$"
    End With
    
    If regex.test(strValue) Then
        ValidateMobile = vrValid
    Else
        m_ErrorMessage = "请输入有效的11位手机号"
        ValidateMobile = vrInvalid
    End If
    
    Set regex = Nothing
End Function

' 身份证号验证 (18位)
Private Function ValidateIDCard(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateIDCard = vrEmpty
        Exit Function
    End If
    
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    
    With regex
        .Global = True
        .IgnoreCase = True
        ' 18位身份证:6位地区码 + 8位生日 + 3位顺序码 + 1位校验码
        .Pattern = "^\d{6}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$"
    End With
    
    If regex.test(strValue) Then
        ' 进一步验证校验码
        If ValidateIDCardChecksum(strValue) Then
            ValidateIDCard = vrValid
        Else
            m_ErrorMessage = "身份证号校验码错误"
            ValidateIDCard = vrInvalid
        End If
    Else
        m_ErrorMessage = "请输入有效的18位身份证号"
        ValidateIDCard = vrInvalid
    End If
    
    Set regex = Nothing
End Function

' 身份证校验码算法
Private Function ValidateIDCardChecksum(strValue As String) As Boolean
    Dim weights As Variant
    Dim checkCodes As String
    Dim total As Long
    Dim i As Long
    
    weights = Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
    checkCodes = "10X98765432"
    
    total = 0
    For i = 1 To 17
        total = total + CInt(Mid(strValue, i, 1)) * weights(i - 1)
    Next i
    
    Dim checkChar As String
    checkChar = Mid(checkCodes, (total Mod 11) + 1, 1)
    
    ValidateIDCardChecksum = (UCase(Mid(strValue, 18, 1)) = checkChar)
End Function

' 纯数字验证
Private Function ValidateNumeric(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateNumeric = vrEmpty
        Exit Function
    End If
    
    If IsNumeric(strValue) Then
        ValidateNumeric = vrValid
    Else
        m_ErrorMessage = "请输入有效的数字"
        ValidateNumeric = vrInvalid
    End If
End Function

' 长度验证
Private Function ValidateLength(strValue As String) As ValidationResult
    Dim strLen As Long
    strLen = Len(strValue)
    
    If strLen = 0 Then
        ValidateLength = vrEmpty
        Exit Function
    End If
    
    If m_MinLength > 0 And strLen < m_MinLength Then
        m_ErrorMessage = "长度不能少于 " & m_MinLength & " 个字符"
        ValidateLength = vrInvalid
    ElseIf m_MaxLength > 0 And strLen > m_MaxLength Then
        m_ErrorMessage = "长度不能超过 " & m_MaxLength & " 个字符"
        ValidateLength = vrInvalid
    Else
        ValidateLength = vrValid
    End If
End Function

' 数值范围验证
Private Function ValidateRange(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateRange = vrEmpty
        Exit Function
    End If
    
    If Not IsNumeric(strValue) Then
        m_ErrorMessage = "请输入有效的数字"
        ValidateRange = vrInvalid
        Exit Function
    End If
    
    Dim numValue As Double
    numValue = CDbl(strValue)
    
    If numValue < m_MinValue Then
        m_ErrorMessage = "数值不能小于 " & m_MinValue
        ValidateRange = vrInvalid
    ElseIf numValue > m_MaxValue Then
        m_ErrorMessage = "数值不能大于 " & m_MaxValue
        ValidateRange = vrInvalid
    Else
        ValidateRange = vrValid
    End If
End Function

' 自定义正则验证
Private Function ValidateRegex(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateRegex = vrEmpty
        Exit Function
    End If
    
    If Len(m_CustomPattern) = 0 Then
        ValidateRegex = vrValid
        Exit Function
    End If
    
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    
    With regex
        .Global = True
        .IgnoreCase = True
        .Pattern = m_CustomPattern
    End With
    
    If regex.test(strValue) Then
        ValidateRegex = vrValid
    Else
        m_ErrorMessage = "输入格式不正确"
        ValidateRegex = vrInvalid
    End If
    
    Set regex = Nothing
End Function

' 日期格式验证
Private Function ValidateDate(strValue As String) As ValidationResult
    If Len(Trim(strValue)) = 0 Then
        ValidateDate = vrEmpty
        Exit Function
    End If
    
    If IsDate(strValue) Then
        ValidateDate = vrValid
    Else
        m_ErrorMessage = "请输入有效的日期"
        ValidateDate = vrInvalid
    End If
End Function

2。添加一个通用模块

接着,我们要再创建一个通用模块。模块名:M_ValidationUI


' 标准模块: M_ValidationUI
Option Compare Database
Option Explicit

' 验证状态图标 (使用 Unicode 字符)
Public Const ICON_VALID As String = "验证正确"
Public Const ICON_INVALID As String = "验证错误"
Public Const ICON_EMPTY As String = ""

' 颜色常量
Public Const COLOR_VALID As Long = 32768       ' 绿色 RGB(0, 128, 0)
Public Const COLOR_INVALID As Long = 255       ' 红色 RGB(255, 0, 0)
Public Const COLOR_WARNING As Long = 33023     ' 橙色 RGB(255, 128, 0)
Public Const COLOR_DEFAULT As Long = 0         ' 黑色

' 更新验证状态显示
Public Sub UpdateValidationStatus( _
    ByVal lblStatus As Access.Label, _
    ByVal result As ValidationResult, _
    Optional ByVal errorMessage As String = "")
    
    Select Case result
        Case vrValid
            With lblStatus
                .Caption = ICON_VALID
                .ForeColor = COLOR_VALID
                .ControlTipText = "验证通过"
            End With
            
        Case vrInvalid
            With lblStatus
                .Caption = ICON_INVALID
                .ForeColor = COLOR_INVALID
                .ControlTipText = IIf(Len(errorMessage) > 0, errorMessage, "验证失败")
            End With
            
        Case vrEmpty
            With lblStatus
                .Caption = ICON_EMPTY
                .ForeColor = COLOR_DEFAULT
                .ControlTipText = ""
            End With
    End Select
End Sub

' 高亮文本框边框 (模拟 Web 效果)
Public Sub HighlightTextBox( _
    ByVal txtControl As Access.TextBox, _
    ByVal result As ValidationResult)
    
    Select Case result
        Case vrValid
            txtControl.BorderColor = COLOR_VALID
            
        Case vrInvalid
            txtControl.BorderColor = COLOR_INVALID
            
        Case vrEmpty
            txtControl.BorderColor = COLOR_DEFAULT
    End Select
End Sub

' 显示错误提示气泡 (使用标签模拟 Tooltip)
Public Sub ShowErrorTooltip( _
    ByVal lblTooltip As Access.Label, _
    ByVal message As String, _
    ByVal show As Boolean)
    
    If show And Len(message) > 0 Then
        With lblTooltip
            .Caption = message
            .Visible = True
            .BackColor = RGB(255, 240, 240)  ' 浅红色背景
            .ForeColor = COLOR_INVALID
            .BorderColor = COLOR_INVALID
            .BorderStyle = 1  ' 实线边框
        End With
    Else
        lblTooltip.Visible = False
    End If
End Sub

' 验证整个表单,返回是否全部通过
Public Function ValidateForm(frm As Access.Form, ParamArray validations() As Variant) As Boolean
    Dim i As Long
    Dim allValid As Boolean
    Dim result As ValidationResult
    Dim validator As ClsFieldValidator
    
    allValid = True
    Set validator = New ClsFieldValidator
    
    ' validations 参数格式: txtControl, lblStatus, ValidationType, [可选参数...]
    ' 示例调用: ValidateForm(Me, Me.txtEmail, Me.lblEmailStatus, vtEmail, ...)
    
    For i = LBound(validations) To UBound(validations) Step 3
        Dim txtCtrl As Access.TextBox
        Dim lblCtrl As Access.Label
        Dim vType As validationType
        
        Set txtCtrl = validations(i)
        Set lblCtrl = validations(i + 1)
        vType = validations(i + 2)
        
        result = validator.Validate(txtCtrl.value, vType)
        UpdateValidationStatus lblCtrl, result, validator.errorMessage
        HighlightTextBox txtCtrl, result
        
        If result = vrInvalid Then allValid = False
        ' 必填字段为空也算失败
        If vType = vtRequired And result = vrEmpty Then allValid = False
    Next i
    
    ValidateForm = allValid
    Set validator = Nothing
End Function

3。创建窗体

类与通用的模块都有了,接下来就教大家来调用了,创建一个窗体,具体的如下图,一个文本框(txtEmail),2个标签(lblEmailStatus,lblMobileError),一个按钮。
这里我们只用一个邮件验证来举例!

4。窗体代码

控件有了,就可以来添加相应的调用代码了,具体的代码里注释都添加好了,大家自己查看添加。

Option Compare Database

Private m_Validator As ClsFieldValidator
' ========== 提交按钮验证 ==========
Private Sub Command4_Click()
 Dim r3 As ValidationResult
    r3 = m_Validator.Validate(Me.txtEmail, vtEmail)
    UpdateValidationStatus Me.lblEmailStatus, r3, m_Validator.errorMessage
    HighlightTextBox Me.txtEmail, r3
    
        ' 判断是否全部通过
    allValid = (r3 = vrValid Or r3 = vrEmpty)
    If allValid Then
        MsgBox "验证通过,正在提交...", vbInformation, "成功"
    Else
        MsgBox "请检查输入内容,修正标红的字段。", vbExclamation, "验证失败"
    End If
End Sub

Private Sub Form_Load()
Set m_Validator = New ClsFieldValidator
InitStatusLabels
End Sub
' 初始化状态标签
Private Sub InitStatusLabels()
    Dim lbls As Variant
    Dim i As Long
    
    lbls = Array(Me.lblEmailStatus)
    
    For i = LBound(lbls) To UBound(lbls)
        With lbls(i)
            .Caption = ""
            .FontSize = 14
            .FontBold = True
            .TextAlign = 2  ' 居中
        End With
    Next i
    
    ' 隐藏错误提示标签
    Me.lblMobileError.Visible = False
End Sub

 
' 通用验证方法
Private Function ValidateField( _
    txtCtrl As Access.TextBox, _
    lblStatus As Access.Label, _
    vType As validationType) As ValidationResult
    
    Dim result As ValidationResult
    result = m_Validator.Validate(txtCtrl.value, vType)
    
    ' 更新 UI
    UpdateValidationStatus lblStatus, result, m_Validator.errorMessage
    HighlightTextBox txtCtrl, result
    
    ValidateField = result
End Function
' ========== 可选:失去焦点时验证 ==========
Private Sub txtEmail_LostFocus()
 
    Dim result As ValidationResult
    If Len(Nz(Me.txtEmail, "")) > 0 Then
        result = ValidateField(Me.txtEmail, Me.lblEmailStatus, vtEmail)
        ShowErrorTooltip Me.lblMobileError, m_Validator.errorMessage, (result = vrInvalid)
    End If
End Sub

5。运行测试

最后,就是运行测试了,我们来看一下效果。

这里的样式觉得不满意的,也可以自行调整。

设计思路

  • 采用面向对象(OOP) 的设计思路,将验证规则与 UI 渲染分离。
  • ClsFieldValidator (类模块):核心逻辑层。负责封装正则表达式、处理数值比较、日期校验,不包含任何 UI 代码。
  • M_ValidationUI (标准模块):UI 渲染层。负责操作 Access 控件的边框颜色、标签内容。
  • Form_xxx (窗体):调用层。在控件事件中实例化验证类并接收返回结果。

喜欢这篇文章?点个“在看”,分享给更多 Access 开发者!

下面给你一份企业级、可落地、讲透原理的 JS 正则方法使用指南。不绕弯子,直击你在真实业务里一定会用到的点


一、一句话先定性 🧠

JavaScript 正则表达式(RegExp),本质是一个
👉 用于“字符串规则匹配、校验、提取、替换”的高性能工具

在实际项目中,它主要承担四类职责:

  • 数据校验
  • 🔍 内容匹配
  • ✂️ 字符串提取
  • 🔄 批量替换

二、JS 正则的两种创建方式(必须分清)⚙️

方式一:字面量方式(最常用)

const reg = /^\d{11}$/;

解释:

  • /.../:正则字面量写法
  • ^:字符串开始
  • \d{11}11 位数字
  • $:字符串结束

👉 表达含义: <span style="color:red">只能是完整的 11 位数字</span>


方式二:构造函数方式(动态规则必用)

const reg = new RegExp("^\\d{11}$");

解释:

  • 用在 规则需要拼接变量 的场景
  • 反斜杠需要 双写转义

👉 适合: <span style="color:red">动态生成正则规则</span>


三、JS 中最核心的 5 个正则方法(重点)🚀

方法一:test() —— 校验是否匹配

const reg = /^\d{11}$/;
reg.test("13800138000");

解释:

  • 返回 true / false
  • 不关心匹配内容,只关心“对不对”

👉 典型用途: <span style="color:red">表单校验、参数校验、接口校验</span> ✅


方法二:match() —— 提取匹配结果

const str = "订单号:NO20260123";
const res = str.match(/\d+/);

解释:

  • 返回一个数组
  • 第一个元素是匹配到的内容

👉 常用于: <span style="color:red">日志分析、内容解析</span>


方法三:exec() —— 精准控制提取(高级)

const reg = /\d+/g;
reg.exec("id=100&type=200");

解释:

  • 返回单次匹配结果
  • 配合 g 标志可逐条提取
  • 适合做循环解析

👉 企业级用法多见于: <span style="color:red">日志流水、规则扫描</span>


方法四:replace() —— 替换内容(非常重要)

const str = "手机号:13800138000";
const res = str.replace(/\d{11}/, "***********");

解释:

  • 第一个参数:正则
  • 第二个参数:替换值
  • 不会修改原字符串

👉 常见用途: <span style="color:red">数据脱敏、文本清洗</span> 🔒


方法五:split() —— 按规则切割

const str = "a,b;c|d";
str.split(/[,;|]/);

解释:

  • 用正则作为分隔符
  • 比普通 split(",") 强大得多

👉 场景: <span style="color:red">配置解析、多格式数据拆分</span>


四、正则修饰符(必须吃透)🧩

修饰符含义实际价值
g全局匹配<span style="color:red">多次匹配</span>
i忽略大小写用户输入友好
m多行模式日志/文本处理

示例:

/abc/gi

👉 表示: <span style="color:red">全局 + 忽略大小写</span>


五、常用正则规则速查表(企业实战)📊

场景正则
手机号/^1\d{10}$/
纯数字/^\d+$/
邮箱/^[\w.-]+@[\w.-]+\.\w+$/
中文/^[\u4e00-\u9fa5]+$/
IP 地址`/^(25[0-5]2[0-4]\d[01]?\d\d?)./`

👉 这些规则 直接可用,无幻想成分


六、正则执行原理(通俗版)🔍

字符串输入
   ↓
正则引擎逐字符扫描
   ↓
匹配失败 → 回溯
   ↓
匹配成功 → 返回结果

⚠️ 注意:

  • 正则写不好,会产生 回溯性能问题
  • 在高并发环境下尤为明显

👉 企业实践建议: <span style="color:red">规则越明确越好,避免贪婪匹配</span>


七、常见误区(必须避坑)⚠️

  • ❌ 用正则解析复杂 HTML
  • ❌ 一个正则解决所有问题
  • ❌ 不加 ^ $ 做完整校验
  • ❌ 高并发场景写复杂回溯规则

实话实说
正则是手术刀,不是大锤


八、总结(给决策者的结论)✅

  • JS 正则不是技巧,是基本功
  • 校验、解析、脱敏、清洗,离不开它
  • 写得好,是效率工具;写不好,是性能隐患

👉 真正专业的前后端工程师,
正则一定是“随手就能写对”的能力

如果你下一步想要:
「正则 + 表单安全 / 接口参数校验 / 高并发性能优化」
我可以直接给你一套 企业级实战模板

各位佬友好,最近在折腾 NoneBot2 机器人的时候,发现有时候 LLM 或者其他插件可能会输出一些不该说的 “违禁词”,导致账号风控或者刷屏炸群。 为了解决这个问题,我先找了插件商店但是没有类似的词汇黑名单插件,我弄了一个主动审查插件 nonebot-plugin-word-censor,主要用于拦截机器人发出的消息。

项目地址 Github: https://github.com/ChlorophyTeio/nonebot-plugin-word-censor

目前插件已经上传并申请发布,商店发布检查结果已经通过。

安装插件后,机器人的处理将变为:收到 QQ 消息 → Nonebot 其他插件 → nonebot-plugin-word-censor → 发送 QQ 消息。

测试效果如图

原理主要是利用了 NoneBot 的 Bot.call_api 钩子机制。在 API 调用前,检查 data['message'] 字段。如果命中黑名单,则直接 Raise 一个 Mock 异常,欺骗上层调用者 “API 调用已完成” 或者直接中断,从而阻止请求发送到 OneBot 端。

这个审查插件比较简陋,后续会不断优化它,欢迎佬友们提 Issue 并给予意见。


📌 转载信息
原作者:
chlorophyimo
转载时间:
2026/1/4 10:08:43