键入

时间:2016-01-21 18:28:54

标签: .net regex vb.net validation

我想定义一个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

2 个答案:

答案 0 :(得分:2)

  

免责声明:我是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

答案 1 :(得分:0)

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

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

这是我的意思的简化示例,但在我的真实项目中,我的示例是一个数组,用于支持正则表达式中的更多复杂性(应测试输入是否与任何样本匹配,如果不匹配则返回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