Torna al Thread
Public Class StringLib
#Region "usi diversi di Split"
''' <summary>
''' estrae l'ennesima parola di una frase
''' </summary>
''' <param name="phrase">la frase</param>
''' <param name="number">il numero della parola (su base zero)</param>
''' <param name="delimiters">i delimitatori o la parola delimitatrice</param>
''' <param name="delimitAsWord">il parametro delimiters è una parola oppure no</param>
''' <returns>parola o stringa vuota</returns>
''' <remarks>usa ExtractWords</remarks>
Public Shared Function ExtractWord(ByVal phrase As String, ByVal number As Integer, _
ByVal delimiters As String, ByVal delimitAsWord As Boolean) As String
Try
If delimitAsWord Then
Dim dd(0) As String
dd(0) = delimiters
Dim words As String() = ExtractWords(phrase, delimiters, delimitAsWord)
Return words(number)
Else
Return ExtractWord(phrase, number, delimiters)
End If
Catch ex As Exception
Return String.Empty
End Try
End Function
''' <summary>
''' estrae l'ennesima parola di una frase
''' </summary>
''' <param name="phrase">la frase</param>
''' <param name="number">il numero della parola (su base zero)</param>
''' <param name="delimiters">i delimitatori (anche uno)</param>
''' <returns>parola o stringa vuota</returns>
''' <remarks>usa ExtractWords</remarks>
Public Shared Function ExtractWord(ByVal phrase As String, ByVal number As Integer, _
ByVal delimiters As String) As String
Try
Dim words As String() = ExtractWords(phrase, delimiters)
Return words(number)
Catch ex As Exception
Return String.Empty
End Try
End Function
''' <summary>
''' estrae l'ennesima parola di una frase
''' </summary>
''' <param name="phrase">la frase</param>
''' <param name="number">il numero della parola (su base zero)</param>
''' <returns>parola o stringa vuota</returns>
''' <remarks>usa ExtractWords e lo spazio come delimitatore</remarks>
Public Shared Function ExtractWord(ByVal phrase As String, ByVal number As Integer) As String
Try
Return ExtractWord(phrase, number, " ", False)
Catch ex As Exception
Return String.Empty
End Try
End Function
''' <summary>
''' estrae tutte le parole di una frase
''' </summary>
''' <param name="phrase">la frase</param>
''' <param name="delimiters">i delimitatori o la parola delimitatrice</param>
''' <param name="delimitAsWord">il parametro delimiters è una parola oppure no</param>
''' <returns>vettore di parole</returns>
Public Shared Function ExtractWords(ByVal phrase As String, ByVal delimiters As String, _
ByVal delimitAsWord As Boolean) As String()
Try
If delimitAsWord Then
Dim dd(0) As String
dd(0) = delimiters
Return phrase.Split(dd, StringSplitOptions.RemoveEmptyEntries)
Else
Return ExtractWords(phrase, delimiters)
End If
Catch ex As Exception
Dim ret As String() = {""}
Return ret
End Try
End Function
''' <summary>
''' estrae tutte le parole di una frase
''' </summary>
''' <param name="phrase">la frase</param>
''' <param name="delimiters">i delimitatori</param>
''' <returns>vettore di parole</returns>
Public Shared Function ExtractWords(ByVal phrase As String, ByVal delimiters As String) As String()
Try
Return phrase.Split(delimiters.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
Catch ex As Exception
Dim ret As String() = {""}
Return ret
End Try
End Function
#End Region
#Region "Filter e IndexOf"
''' <summary>
''' conta le ricorrenze di una stringa in un testo
''' </summary>
''' <param name="testo">testo in cui cercare</param>
''' <param name="parola">testo da cercare</param>
''' <param name="caseSensitive">ignorare o no maiuscole-minuscole</param>
''' <returns>il numero delle ricorrenze trovate</returns>
Public Shared Function CountWord(ByVal testo As String, ByVal parola As String, _
ByVal caseSensitive As Boolean) As Integer
Return CountWord(testo, parola, caseSensitive, False)
End Function
''' <summary>
''' conta le ricorrenze di una parola in un testo
''' </summary>
''' <param name="testo">testo in cui cercare</param>
''' <param name="parola">parola da cercare</param>
''' <param name="caseSensitive">ignorare o no maiuscole-minuscole</param>
''' <param name="distinct">considerare o no parole intere</param>
''' <returns>il numero delle ricorrenze trovate</returns>
Public Shared Function CountWord(ByVal testo As String, ByVal parola As String, _
ByVal caseSensitive As Boolean, ByVal distinct As Boolean) As Integer
Try
If distinct Then
Dim cm As CompareMethod
If caseSensitive Then
cm = CompareMethod.Binary
Else
cm = CompareMethod.Text
End If
Dim words As String() = ExtractWords(testo, " ,.;:!/()?-_+", False)
Dim matches As String() = Strings.Filter(words, parola, True, cm)
Return matches.Length
Else
Dim conto As Integer = 0
Dim pos As Integer = 0
Dim sc As System.StringComparison
If testo = String.Empty Then Return 0
If caseSensitive Then
sc = StringComparison.Ordinal
Else
sc = StringComparison.OrdinalIgnoreCase
End If
pos = testo.IndexOf(parola, sc)
Do While pos <> -1
conto += 1
pos = testo.IndexOf(parola, pos + Len(parola), sc)
Loop
Return conto
End If
Catch ex As Exception
Return 0
End Try
End Function
#End Region
#Region "Extended Replace"
''' <summary>
''' traduce in un testo passato ogni carattere tra quelli indicati
''' in una stringa nel corrispondente carattere di una altra stringa
''' </summary>
''' <param name="testo">testo da tradurre</param>
''' <param name="charsMapIn">stringa coi caratteri da cercare</param>
''' <param name="charsMapOut">stringa coi caratteri da usare</param>
''' <returns>il testo tradotto</returns>
''' <remarks>se la lunghezza di charsMapOut è minore della lunghezza di charsMapIn
''' viene usato un solo carattere di sostituzione, il primo di charsMapOut</remarks>
Public Shared Function Translate(ByVal testo As String, ByVal charsMapIn As String, _
ByVal charsMapOut As String) As String
If charsMapIn.Length > charsMapOut.Length Then
charsMapOut = New String(charsMapOut.Chars(0), charsMapIn.Length)
End If
For i As Integer = 0 To charsMapOut.Length - 1
testo.Replace(charsMapIn.Chars(i), charsMapOut.Chars(i))
Next
Return testo
End Function
''' <summary>
''' Sostituisce i parametri 1% 2% 3%... in una stringa con le rispettive parole passate
''' </summary>
''' <param name="testo">testo in cui effettuare le modifiche</param>
''' <param name="tokens">vettore di parole</param>
''' <returns>testo modificato</returns>
Public Shared Function ReplaceToken(ByVal testo As String, ByVal tokens As String()) As String
For i As Integer = 0 To tokens.Length - 1
testo.Replace(i.ToString & "%", tokens(i))
Next
Return testo
End Function
#End Region
''' <summary>
''' restituisce la stringa passata a caratteri invertiti da destra a sinistra
''' </summary>
Public Shared Function ReverseString(ByVal testo As String) As String
Dim arr As Char() = testo.ToCharArray
Array.Reverse(arr)
Return New String(arr)
End Function
''' <summary>
''' capitalizza la stringa passata
''' </summary>
Public Shared Function ToProper(ByVal stringa As String) As String
Return stringa.Substring(0, 1).ToUpper & stringa.Substring(1).ToLower
End Function
#Region "Soundex e c."
''' <summary>
''' restituisce il codice SoundEx di una parola
''' </summary>
''' <param name="word">parola</param>
''' <returns>codice</returns>
Public Shared Function Soundex(ByVal word As String) As String
Dim soundexChars(3) As Char
Dim i As Integer, j As Integer
Dim dChar, oldChar, aChar As Char
Const alphabetList As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Const soundexCodes As String = "01230120022455012623010202"
' soundex is case-insensitive
word = word.ToUpper
' the first letter is copied in the result
soundexChars(0) = word.Chars(0)
j += 1
oldChar = soundexCodes.Chars(alphabetList.IndexOf(word.Chars(0)))
For i = 1 To word.Length - 1
aChar = word.Chars(i)
' discard non-alphabetic chars
If Char.IsLetter(aChar) Then
' convert to a digit
dChar = soundexCodes.Chars(alphabetList.IndexOf(aChar))
' don't insert repeated digits
If dChar <> "0"c And dChar <> oldChar Then
soundexChars(j) = dChar
j += 1
If j = 4 Then Exit For
End If
oldChar = dChar
End If
Next
Return New String(soundexChars)
End Function
''' <summary>
''' restituisce un valore di assonanza tra due parole
''' </summary>
''' <param name="first">prima parola</param>
''' <param name="second">seconda parola</param>
''' <param name="areSoundex">le parole sono codici SoundEx?</param>
''' <returns>un valore tra 0 (nessuna assonanza) e 4 (assonanza completa)</returns>
Public Shared Function SoundsLikeDegree(ByVal first As String, ByVal second As String, _
Optional ByVal areSoundex As Boolean = False) As Integer
Dim degree As Integer = 0
If areSoundex Then
first = Soundex(first)
second = Soundex(second)
End If
For i As Integer = 0 To 3
If first.Chars(i) <> second.Chars(i) Then Exit For
degree += 1
Next
Return degree
End Function
#End Region
#Region "da numero in lettere"
''' <summary>
''' converte un numero in lettere
''' </summary>
''' <param name="numero">numero da convertire</param>
''' <returns>il numero convertito in lettere</returns>
Public Shared Function NumToLet(ByVal numero As Decimal) As String
' stringa da restituire
Dim lettere As String = String.Empty
' conversione in stringa lunga 21 caratteri comunque
Dim sNumero As String = numero.ToString("G21")
' verifica se numero troppo lungo (forma esponenziale)
Dim i As Integer = sNumero.IndexOf("E")
If i <> -1 Then ' esponenziale!
Throw New OverflowException("Numero troppo lungo per essere convertito")
End If
' verifica dei decimali
Dim decimali As Decimal = Decimal.Subtract(numero, Decimal.Truncate(numero))
If decimali > 0 Then
' se ci sono vengono letti e separati
sNumero = decimali.ToString().Substring(2)
lettere = String.Concat(NumToLet(Decimal.Truncate(numero)), " e ", _
NumToLet(Decimal.Parse(sNumero)))
Else
' verifica se zero
If numero = 0 Then
lettere = "zero"
Else
' formattazione a 21 caratteri per avere comunque tutti i gruppi
sNumero = sNumero.PadLeft(21, "0"c)
Dim terzina As String, groups As Integer
' per ogni gruppo estraggo e risolvo la terzina ed il gruppo
For i = 0 To 18 Step 3
groups += 1
terzina = sNumero.Substring(i, 3)
If CInt(terzina) > 0 Then
lettere &= RisolviTerzina(terzina) & GrpToParola(groups, CInt(terzina) = 1)
End If
Next
End If
End If
Return lettere
End Function
''' <summary>
''' converte un numero in lettere, nel formato prescelto
''' </summary>
''' <param name="numero">numero da convertire</param>
''' <param name="outputFormat">formato</param>
''' <returns>il numero convertito in lettere formattate</returns>
Public Shared Function NumToLet(ByVal numero As Decimal, _
ByVal outputFormat As EnumNumToLetFormat) As String
Select Case outputFormat
Case EnumNumToLetFormat.Maiuscolo
Return NumToLet(numero).ToUpper
Case EnumNumToLetFormat.Capitalizzato
Return ToProper(NumToLet(numero))
Case EnumNumToLetFormat.Minuscolo
Return NumToLet(numero).ToLower
End Select
End Function
''' <summary>
''' converte in lettere un importo in Euro, nella forma numero/nn
''' </summary>
''' <param name="numero">importo da convertire</param>
''' <returns>importo convertito in lettere</returns>
Public Shared Function EurToLet(ByVal numero As Decimal) As String
Dim lettere As String = ""
Dim sNumero As String = numero.ToString("G21")
Dim i As Integer = sNumero.IndexOf("E")
If i <> -1 Then ' esponenziale!
Throw New OverflowException()
End If
Dim decimali As Decimal = Decimal.Subtract(numero, Decimal.Truncate(numero))
If decimali > 0 Then
sNumero = decimali.ToString().Substring(2)
If sNumero.Length > 2 Then _
Throw New NotSupportedException("I decimali non possono essere più di due")
sNumero = sNumero.PadRight(2, "0"c)
lettere = NumToLet(Decimal.Truncate(numero)) + "/" + sNumero
Else
lettere = NumToLet(Decimal.Truncate(numero)) + "/00"
End If
Return lettere
End Function
''' <summary>
''' converte in lettere un importo in Euro, nella forma numero/nn e nel formato prescelto
''' </summary>
''' <param name="numero">importo da convertire</param>
''' <param name="outputFormat">formato</param>
''' <returns>importo convertito in lettere e formattato</returns>
Public Shared Function EurToLet(ByVal numero As Decimal, _
ByVal outputFormat As EnumNumToLetFormat) As String
Select Case outputFormat
Case EnumNumToLetFormat.Maiuscolo
Return EurToLet(numero).ToUpper
Case EnumNumToLetFormat.Capitalizzato
Return ToProper(EurToLet(numero))
Case EnumNumToLetFormat.Minuscolo
Return EurToLet(numero).ToLower
End Select
End Function
''' <summary>
''' traduce una terzina di cifre in lettere
''' </summary>
Private Shared Function RisolviTerzina(ByVal cifre As String) As String
' caso particolare 'uno': risolto attraverso GrpToParola
If Integer.Parse(cifre) = 1 Then Return ""
Dim lettere As String = String.Empty
Dim cifra1 As Byte = CByte(cifre.Substring(0, 1))
Dim cifra2 As Byte = CByte(cifre.Substring(1, 1))
Dim cifra3 As Byte = CByte(cifre.Substring(2, 1))
' prima cifra
Dim depo As String = "cento"
If cifra1 = 1 Then lettere = depo
If cifra1 > 1 Then lettere = NumToParola(cifra1) & depo
' seconda cifra: test per troncare l'ultima vocale
If cifra2 > 0 Then depo = NumToParola(cifra2 * 10)
If cifra2 > 1 And (cifra3 = 1 Or cifra3 = 8) Then
lettere &= Left(depo, depo.Length - 1)
ElseIf cifra2 > 1 And cifra3 > 1 Then
lettere &= depo
ElseIf cifra2 > 0 Then
lettere &= NumToParola(cifra2 * 10 + cifra3)
cifra3 = 0 ' in quanto già elaborata
End If
' terza cifra
If cifra3 > 0 Then lettere &= NumToParola(cifra3)
Return ToProper(lettere)
End Function
''' <summary>
''' restituisce la parola corrispondente alla cifra
''' </summary>
Private Shared Function NumToParola(ByVal cifra As Integer) As String
If cifra <= 19 Then
Return Choose(cifra, "uno", "due", "tre", "quattro", "cinque", "sei", "sette", _
"otto", "nove", "dieci", "undici", "dodici", "tredici", _
"quattordici", "quindici", "sedici", "diciassette", _
"diciotto", "diciannove").ToString
Else
Return Choose(cifra / 10, "", "venti", "trenta", "quaranta", "cinquanta", _
"sessanta", "settanta", "ottanta", "novanta").ToString
End If
End Function
''' <summary>
''' restituisce la parola corrispondente al gruppo
''' </summary>
Private Shared Function GrpToParola(ByVal grp As Integer, ByVal uno As Boolean) As String
If uno Then
Return Choose(grp, "Unmiliardodimiliardi", "Unmilionedimiliardi", "Millemiliardi", _
"Unmiliardo", "Unmilione", "Mille", "Uno").ToString
Else
Return Choose(grp, "miliardidimiliardi", "milionidimiliardi", "milamiliardi", _
"miliardi", "milioni", "mila", "").ToString
End If
End Function
''' <summary>
''' converte un numero tra 1 e 3999 in numero romano
''' </summary>
Public Shared Function NumToRoman(ByVal numero As Integer) As String
Dim cifreRomane() As Char = "IVXLCDM".ToCharArray
Dim pos As Integer = 0
Dim cifra As Integer
Dim sb As New System.Text.StringBuilder
If numero < 1 Or numero > 3999 Then
Throw New IndexOutOfRangeException("il numero non è tra 1 e 3999")
End If
Do While numero > 0
cifra = numero Mod 10
numero = numero \ 10
Select Case cifra
Case 1
sb.Insert(0, cifreRomane(pos))
Case 2
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
Case 3
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
Case 4
sb.Insert(0, cifreRomane(pos + 1))
sb.Insert(0, cifreRomane(pos))
Case 5
sb.Insert(0, cifreRomane(pos + 1))
Case 6
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos + 1))
Case 7
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos + 1))
Case 8
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos))
sb.Insert(0, cifreRomane(pos + 1))
Case 9
sb.Insert(0, cifreRomane(pos + 2))
sb.Insert(0, cifreRomane(pos))
End Select
pos = pos + 2
Loop
Return sb.ToString
End Function
#End Region
End Class
''' <summary>
''' formato dell'output di NumToLet
''' </summary>
''' <remarks></remarks>
Public Enum EnumNumToLetFormat As Byte
Maiuscolo
Minuscolo
Capitalizzato
End Enum