Long ago we did a Redmond VisualBasic Developers Association presentation on how to create and use VB collections. Many from the audience liked it more for what it did than how it did it. I was surpised to see the hitcount on that old code's page still being relatively high so I figured I'd bring it up to the 21st century. For this VB.Net port, the old demonstration classes and collections have been removed and just the functionality remains. If you like StrConv but need it to really do the job, stick this class in your project and let it do the work for you. 
The class is really simple to use and you have control over whether you fix acronyms, embedded apostrophes or both. Notice that the acronym fixer also knows how to deal with periods that are not in acronyms (as in "Jr."), the apostrophe routine accounts for possessives while fixing both the single quote and the "`" (that thing under the "~", next to the 1 key. For some reason, direct mail companies like to use that character interchangeably with the apostrophe and it's really annoying). Are there better ways? Sure, but this way works with the extra touches and is already written for you <g>
Public Class ApostonymFixer
Private m_arPhrase() As String
Public Enum rcsTypeOfCheck
rcsCheckAcronym = 0
rcsCheckApostrophe = 1
rcsCheckApostroNym = 2
End Enum
Public Function FixText(ByVal textToCheck As String, _
Optional ByVal typeOfCheck As rcsTypeOfCheck = rcsTypeOfCheck.rcsCheckApostroNym) _
As String
PrepareText(textToCheck)
Select Case typeOfCheck
Case rcsTypeOfCheck.rcsCheckAcronym
'uppercase letters before and
'after the dot
FixAcronym()
Case rcsTypeOfCheck.rcsCheckApostrophe
FixApostrophe()
Case rcsTypeOfCheck.rcsCheckApostroNym
FixAcronym()
FixApostrophe()
End Select
Return String.Join(" ", m_arPhrase)
End Function
Private Sub FixAcronym()
Dim i As Integer
Dim TempWord As String
'just for fun use ForEach in this one and an int indexer in the other one
For Each s As String In m_arPhrase
'pad for lookaheads
TempWord = s & " "
i = 1
Do Until i = Len(TempWord)
If i > 1 Then
If Mid(TempWord, i, 1) = "." Then
Mid(TempWord, i - 1, 3) = Mid(TempWord, i - 1, 3).ToUpper
End If
'this takes care of things
'like Jr.
If i > 2 Then
If Mid(TempWord, i, 1) = "." And Mid(TempWord, i - 2, 1) <> "." Then
Mid(TempWord, i - 1, 1) = Mid(TempWord, i - 1, 1).ToLower
End If
End If
End If
i += 1
Loop
'kill the pad
'and update the array element
s = TempWord.Trim
Next
End Sub
Private Sub FixApostrophe()
Dim tempWord As String
Dim foundAt As Integer
'just for fun use an int indexer in this and a ForEach in the other one
For iCounter As Integer = 0 To m_arPhrase.Length - 1
tempWord = m_arPhrase(iCounter).ToString & " "
foundAt = tempWord.IndexOf("'"c)
If foundAt = 1 AndAlso Len(tempWord) > 2 Then
tempWord = Mid(tempWord, 1, 1).ToUpper & "'" & _
Mid(tempWord, foundAt + 2, 1).ToUpper & _
Mid(tempWord, foundAt + 3, Len(tempWord) - foundAt).ToLower
End If
m_arPhrase(iCounter) = tempWord.Trim
'this also works but does more iteration
'than is typically required
'the foundAt variable isn't required for this
'For i As Integer = 1 To Len(TempWord)
' If Mid(tempWord, i, 1) = "'" Then
' If Mid(tempWord, i + 2, 1) <> " " AndAlso i = 2 Then
' Mid(tempWord, i + 1, 1) = Mid(tempWord, i + 1, 1).ToUpper
' Else
' Mid(tempWord, i + 1, 1) = Mid(tempWord, i + 1, 1).ToLower
' End If
' End If
'Next
Next
End Sub
Private Sub PrepareText(ByVal phrase As String)
'get rid of double spaces
Do While phrase.IndexOf(" ") > 0
phrase = phrase.Trim.Replace(" ", " ")
Loop
'get rid of the abnormal slash
'CHECK WITH YOUR PM to make sure that you're not the one company
'in the world that uses this character
phrase = phrase.Trim.Replace("`", "'")
'init to proper
phrase = StrConv(phrase, VbStrConv.ProperCase)
'the traditional keyword is also fine:
'phrase = StrConv(phrase, vbProperCase)
'split to the array
m_arPhrase = phrase.Split(" "c)
End Sub
End ClassWhy the Mids instead of .Net's SubString? If you use VB.Net or call into the core Framework VisualBasic.Dll from any other language then then using the Mid, Left and Rights means not having the allocation overhead of .Net immutable strings; That's a trick that comes in handy in code like we have above. MS documents the use of the optimized traditional keywords in some cases at up to 85% better performance over the Framework's SubString and thus for some performance situations Microsoft recommends the Microsoft.VisualBasic.dll string functions over the Framework's SubString. Hope it helps.
Robert Smith
Kirkland WA originally added to smithvoice Sept 15 1999, .Net code page added August 2005 |