Qual è il modo migliore per determinare se un carattere è una lettera in VB6?
-
01-07-2019 - |
Domanda
Serve una funzione che prenda un carattere come parametro e restituisca vero se è una lettera.
Soluzione
Seanyboy's IsCharAlphaA
risposta è chiuso.Il metodo migliore è utilizzare la versione W in questo modo:
Private Declare Function IsCharAlphaW Lib "user32" (ByVal cChar As Integer) As Long
Public Property Get IsLetter(character As String) As Boolean
IsLetter = IsCharAlphaW(AscW(character))
End Property
Naturalmente, tutto ciò ha raramente importanza poiché tutti i controlli di VB6 sono solo ANSI
Altri suggerimenti
Questo faceva parte del codice pubblicato da rpetrich in risposta ad a domanda di Joel Spolsky.Ho sentito che era necessario un post specifico per il problema che risolve.È davvero geniale.
Private Function IsLetter(ByVal character As String) As Boolean
IsLetter = UCase$(character) <> LCase$(character)
End Function
Potresti pensare a te stesso: "Funzionerà sempre?" La documentazione sulle funzioni ucase e lcase, conferma che:
Funzione UCase Solo le lettere minuscole vengono convertite in maiuscole; tutte le lettere maiuscole e i caratteri non alfabetici rimangono invariati.
Funzione LCase Solo le lettere maiuscole vengono convertite in minuscole; tutte le lettere minuscole e i caratteri non alfabetici rimangono invariati.
Private Function IsLetter(Char As String) As Boolean
IsLetter = UCase(Char) Like "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
End Function
Cosa c'è di sbagliato in quanto segue, che non si basa su un comportamento linguistico oscuro?
Private Function IsLetter(ByVal ch As String) As Boolean
IsLetter = (ch >= "A" and ch <= "Z") or (ch >= "a" and ch <= "z")
End Function
Credo che possiamo migliorare ancora un po' questo aspetto. rpetrichfunzionerà, ma forse solo per fortuna.Il parametro della chiamata API dovrebbe essere un TCHAR (WCHAR qui in realtà) e non un Long.Ciò significa anche che non dovrai preoccuparti della conversione in Long o del mascheramento con &HFFFF.Questo tra l'altro è Integer e anche qui aggiunge una conversione implicita a Long.Forse intendeva &HFFFF& in questo caso?
Oltre a ciò, potrebbe essere meglio chiamare esplicitamente il wrapper UnicoWS per questa chiamata API, per la compatibilità con Win9X.Potrebbe essere necessario distribuire UnicoWS.dll, ma almeno otteniamo questa opzione.Poi ancora forse da VB6 questo viene reindirizzato automaticamente, non ho Win9X installato per testarlo.
Option Explicit
Private Declare Function IsCharAlphaW Lib "unicows" (ByVal WChar As Integer) As Long
Private Function IsLetter(Character As String) As Boolean
IsLetter = IsCharAlphaW(AscW(Character))
End Function
Private Sub Main()
MsgBox IsLetter("^")
MsgBox IsLetter("A")
MsgBox IsLetter(ChrW$(&H34F))
MsgBox IsLetter(ChrW$(&HFEF0))
MsgBox IsLetter(ChrW$(&HFEFC))
End Sub
Guardandomi un po' intorno mi venne fuori quanto segue...
Private Declare Function IsCharAlphaA Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long
Credo che IsCharAlphaA testi i set di caratteri ANSI e IsCharAlpha test ASCII.Potrei sbagliarmi.
Private Function IsAlpha(ByVal vChar As String) As Boolean
Const letters$ = "abcdefghijklmnopqrstuvwxyz"
If InStr(1, letters, LCase$(vChar)) > 0 Then IsAlpha = True
End Function
Lo uso in VBA
Function IsLettersOnly(Value As String) As Boolean
IsLettersOnly = Len(Value) > 0 And Not UCase(Value) Like "*[!A-Z]*"
End Function
Non si documenta esattamente da solo.E potrebbe essere lento.È un trucco intelligente, ma è tutto.Sarei tentato di essere più ovvio nel mio controllo.Usa le espressioni regolari o scrivi un test più ovvio.
public bool IsAlpha(String strToCheck)
{
Regex objAlphaPattern=new Regex("[^a-zA-Z]");
return !objAlphaPattern.IsMatch(strToCheck);
}
public bool IsCharAlpha(char chToCheck)
{
return ((chToCheck=>'a') and (chToCheck<='z')) or ((chToCheck=>'A') and (chToCheck<='Z'))
}