【问题标题】:validate strings using a regular expression while typing在键入时使用正则表达式验证字符串
【发布时间】:2016-04-28 03:47:37
【问题描述】:

我想定义一个 RegEx 验证器函数,它根据定义的 RegEx在键入时检查每个字符而不仅仅是在输入整个字符串之后):

Public Class RegExValidator
    Inherits System.Windows.Forms.TextBox

    Private regex As New System.Text.RegularExpressions.Regex("[1-9-]\/[1-9-][\-+][abo][\/]some\-number\:\d{1,5}")

    Public Function CheckUserInput(ByVal input As String) As Boolean
        ' this only checks whole input so for 
        'beggining parts of input it returns 
        'false and protects users to finish
        'their correct input
        If regex.IsMatch(input) Then
            Return True
        Else
            ' should check if currect input is matching 
            'beggining parts of RegEx and if not matches
            'some part of RegEx return false
            'else return true
        End If
    End Function

    ' I'm going to override PreProccessMessage() 
    'on real application but this is just a
    'sample to demonstrate my problem simply
    Protected Overrides Sub OnTextChanged(e As EventArgs)
        MyBase.OnTextChanged(e)
        If Not CheckUserInput(Me.Text) Then
            MsgBox("Validation failed! This character is not allowed!")
            Me.Text = Me.old_text
        End If
    End Sub

    Private old_text As String
    Public Overrides Property Text As String
        Get
            Return MyBase.Text
        End Get
        Set(value As String)
            Me.old_text = Me.Text
            MyBase.Text = value
        End Set
    End Property

End Class

【问题讨论】:

  • @halfer 好的,如果您喜欢这种方式,没问题 :) 如果我第一次无视您的帮助,请原谅。感谢您的关心。
  • 好的,谢谢雷蒙!
  • @halfer 不客气。

标签: .net regex vb.net validation


【解决方案1】:

免责声明:我是PCRE.NET的作者。

您所要求的称为部分匹配 - 也就是说,将部分输入与模式匹配。

不幸的是,.NET 正则表达式引擎不支持开箱即用。修改模式可能会成功,但很快就会变得很麻烦,而且在一般情况下并不容易。

幸运的是,此功能由PCRE 库提供,您可以通过我的PCRE.NET 包装器使用它。

所以你安装包:

Install-Package PCRE.NET

然后你使用PcreRegex 类而不是Regex。您需要使用以下选项之一:PcreMatchOptions.PartialSoftPcreMatchOptions.PartialHard

PCRE's docs for partial matching(我鼓励您阅读)说以下内容:

这两个选项之间的区别在于,部分匹配是否比完全匹配更可取,尽管这两种匹配函数的细节有所不同。

因此,您可以选择最适合您的需求。

您的代码可能如下所示:

Imports PCRE
Private regex As New PcreRegex("^[1-9-]/[1-9-][-+][abo]/some-number:\d{1,5}$")

Public Function CheckUserInput(ByVal input As String) As Boolean
    Dim match = regex.Match(input, PcreMatchOptions.PartialSoft)

    If match.Success Then
        ' The input is valid
        Return True
    ElseIf match.IsPartialMatch Then
        ' The input is valid so far, but there's still a required part missing
        Return True
    Else
        ' The input is NOT valid
        Return False
    End If
End Function

match.Success 表示完全匹配,而match.IsPartialMatch 表示输入不足但部分有效。请注意,我将您的模式包含在 ^$ 锚点中,以禁止额外的意外输入。

请注意,PCRE 和 .NET 风格略有不同,但基本功能相同。你可以compare them here

【讨论】:

  • 感谢您提供这么好的信息/解决方案。目前我无法测试(需要时间),但我会尽快测试,你的答案应该是正确的。
【解决方案2】:

技巧:在测试前使用示例字符串完成输入

我使用了一个技巧来做到这一点,我的技巧是使用一些示例字符串(每个字符串应该展示正则表达式匹配的不同场合)作为补充,如果输入长度不足以丰富接受匹配,则在测试匹配之前使用示例临时完成输入的字符串,以测试它是否可以匹配。

这是我的意思的简化示例,但在我的实际项目中,我的示例是一个数组,用于支持更复杂的正则表达式(应测试输入是否与任何示例匹配,如果不匹配则返回 false):

' sample should match the regular expression
Private Const sample As String = "1/1+a/some-number:6"

Public Function check_partial_match(ByVal input As String) as boolean
    If input.Length >= sample.Length Then
        Return False
    End If
    Dim teststr As String = sample.Remove(0, input.Length)
    teststr = input & teststr
    Return regex.IsMatch(teststr)
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多