Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
I have a windows forms application that has a textbox for users to enter special comments about their work. We've been having trouble because users have been using Microsoft Word to type these comments and then they copy/paste them into my application. It's a problem because, for example, in Word if you type ... it converts it to an elipse character. Also if you type - it can convert it into a hyphen character. These are fine to paste into the textbox, but eventually this data is getting saved to an iSeries which doesn't like these characters. So I put together some code which should work both as the user types and if they use copy/paste to replace known trouble characters with counterparts and any unkown characters with an asterisk. It works, but I have a feeling there must be a better and more efficient way to do it. Does anyone have any suggestions?
VB
Private Sub txtSpecialReport_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtSpecialReport.TextChanged
        'Only allow known characters to be pasted or typed into txtSpecialReport to avoid errors on iSeries
        '\w is for a-zA-Z0-9, \s is for spaces, tabs, returns, the rest are allowed special characters
        Dim myRegex As New System.Text.RegularExpressions.Regex("[\w\s\!\@\#\$\%\^\&\*\(\)\-\=\+\[\]\{\}\\\|\;\:\'\,\<\.\>\/\?\""]")
        Dim sb As New System.Text.StringBuilder
        Dim intStart As Integer = txtSpecialReport.SelectionStart
        For Each myChar As Char In txtSpecialReport.Text.ToCharArray
            If Not myRegex.IsMatch(myChar) Then
                'known replacements
                Select Case Asc(myChar)
                    Case 63
                        'Replace an ascii 63 with ascii 39
                        myChar = "'"
                    Case 133
                        'Replace an ascii 133 elipses with a period
                        'don't want to change the length of the string, so don't replace with three periods
                        myChar = "."
                    Case 146
                        'Replace an ascii 146 with ascii 39
                        myChar = "'"
                    Case 150
                        'Replace an ascii 150 dash with an ascii 45 dash
                        myChar = "-"
                    Case Else
                        'Any other characters replace with an asterisk
                        myChar = "*"
                End Select
            End If
            sb.Append(myChar)
        Next
        txtSpecialReport.Text = sb.ToString
        txtSpecialReport.SelectionStart = intStart
    End Sub
Posted

1 solution

Unfortunately, AFAIK there is no way top make a regex which replaces "one of these" with "one of those".
You can clean it up a bit, by using a MatchEvaluator to remove the need for a String builder. Make the regex just a list of known invalid characters and:
result = myRegex.Replace(input, New MatchEvaluator(AddressOf ReplaceSpecials))

Private Function ReplaceSpecials(match As Match) As String
	Select Case Asc(match.Value(0))
		Case 63
			Return "'"
		Case 133
			Return "."
	End Select
	Return "*"
End Function
This isn't tested, but you get the general idea: See MSDN[^] for better details.


-- KSCHULER EDIT: Added the "AddressOf" keyword that was missing to correct syntax and removed ;
 
Share this answer
 
v2
Comments
Kschuler 30-Mar-11 11:39am    
I had never really even noticed the .Replace on the RegEx object. Thanks. This does seem a lot nicer than using the stringbuilder. I just edited your code block for a few syntax things I found. This is exactly the kind of suggestion I was hoping for.
OriginalGriff 30-Mar-11 14:22pm    
Cheers for the fixes, I said it wasn't tested - normally I do this stuff in C#, so I just did a quick translation. Or half a translation, perhaps! :laugh:
Sergey Alexandrovich Kryukov 30-Mar-11 12:52pm    
My 5.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900