Trong Posted 3 hours ago Posted 3 hours ago I had a dissatisfaction with IsNumber so this function was born: expandcollapse popup; AutoIt Data Type Checker - Single Main Function + Demo Helper ; Main function contains ALL logic, helper function only for demo/testing ; Parameters: ; $vInput - Variable/value to check (any type) ; $bStrictMode - Boolean (optional): True for strict hex checking (even length), False for loose (default: False) ; $bShowDebug - Boolean (optional): True to show debug info, False to hide (default: False) ; Returns: ; -1 = Unknown type ; 0 = String types (Empty, Path, URL, Email, Numeric String, Alphabetic String) ; 1 = Number types (Integer, Float, Number, String Integer, String Float, String Number) ; 2 = Binary/Hex types (Binary, Hex String) ; 4 = Boolean types (Boolean, String Boolean) ; 5 = Array, 6 = Map, 7 = Pointer, 8 = DLL Struct, 9 = Window Handle, 10 = Object Func CheckDataType($vInput, $bStrictMode = False, $bShowDebug = False) ; ============================================================================ ; SHOW DEBUG INFO ; ============================================================================ If $bShowDebug Then ConsoleWrite("- [DEBUG] Input: " & VarGetType($vInput) & " '" & String($vInput) & "' | Mode: " & ($bStrictMode ? "Strict" : "Loose") & @CRLF) EndIf ; ============================================================================ ; CHECK AUTOIT OBJECT TYPES FIRST (Highest Priority) ; ============================================================================ If IsArray($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsArray() = True -> Array (5)" & @CRLF) Return 5 EndIf If IsMap($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsMap() = True -> Map (6)" & @CRLF) Return 6 EndIf If IsPtr($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsPtr() = True -> Pointer (7)" & @CRLF) Return 7 EndIf If IsDllStruct($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsDllStruct() = True -> DLL Struct (8)" & @CRLF) Return 8 EndIf If IsHWnd($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsHWnd() = True -> Window Handle (9)" & @CRLF) Return 9 EndIf If IsObj($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsObj() = True -> Object (10)" & @CRLF) Return 10 EndIf ; ============================================================================ ; CHECK BINARY TYPES ; ============================================================================ If IsBinary($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsBinary() = True -> Binary/Hex (2)" & @CRLF) Return 2 EndIf ; ============================================================================ ; CHECK BOOLEAN TYPES ; ============================================================================ If IsBool($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsBool() = True -> Boolean (4)" & @CRLF) Return 4 EndIf ; ============================================================================ ; CHECK NUMBER TYPES (Built-in IsNumber is most reliable) ; ============================================================================ If IsNumber($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: IsNumber() = True -> Number (1)" & @CRLF) Return 1 EndIf ; ============================================================================ ; STRING ANALYSIS (Most Complex Part) ; ============================================================================ If IsString($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Processing as string..." & @CRLF) ; ------------------------------------------------------------------------ ; CHECK STRING NUMBERS (Highest Priority for Strings) ; ------------------------------------------------------------------------ ; Check AutoIt built-in string number functions first If StringIsInt($vInput) Or StringIsFloat($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: StringIsInt/Float = True -> Number (1)" & @CRLF) Return 1 EndIf ; Check simple number conversion Local $fNumValue = Number($vInput) If (String($fNumValue) = StringStripWS($vInput, 8)) And (StringStripWS($vInput, 8) <> "") Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: String convertible to number -> Number (1)" & @CRLF) Return 1 EndIf ; ------------------------------------------------------------------------ ; CHECK INTERNATIONAL NUMBER FORMATS (Inline Logic) ; ------------------------------------------------------------------------ ; Remove leading/trailing spaces for international number checking Local $sClean = StringStripWS($vInput, 3) If $sClean <> "" Then ; Check for optional negative sign Local $sNumberPart = $sClean If StringLeft($sNumberPart, 1) = "-" Then $sNumberPart = StringMid($sNumberPart, 2) EndIf ; US Format: 1,234.56 or 1,234,567.89 (comma thousands, dot decimal) Local $sUSPattern = "^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?$" If StringRegExp($sNumberPart, $sUSPattern) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: US number format -> Number (1)" & @CRLF) Return 1 EndIf ; EU Format: 1.234,56 or 1.234.567,89 (dot thousands, comma decimal) Local $sEUPattern = "^[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)?$" If StringRegExp($sNumberPart, $sEUPattern) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: EU number format -> Number (1)" & @CRLF) Return 1 EndIf ; Thousands separator only: 1,234 or 1.234 (no decimal part) If StringRegExp($sNumberPart, "^[0-9]{1,3}[,\.][0-9]{3}([,\.][0-9]{3})*$") Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: Thousands separator format -> Number (1)" & @CRLF) Return 1 EndIf ; Simple EU decimal: 1,5 (comma as decimal separator) If StringRegExp($sNumberPart, "^[0-9]+,[0-9]+$") Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: EU decimal format -> Number (1)" & @CRLF) Return 1 EndIf EndIf ; ------------------------------------------------------------------------ ; CHECK BOOLEAN-LIKE STRINGS ; ------------------------------------------------------------------------ Local $sLowerInput = StringLower(StringStripWS($vInput, 3)) If $sLowerInput = "true" Or $sLowerInput = "false" Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: Boolean-like string -> Boolean (4)" & @CRLF) Return 4 EndIf ; ------------------------------------------------------------------------ ; CHECK HEXADECIMAL STRINGS (Inline Logic) ; ------------------------------------------------------------------------ Local $bIsHex = False If $bStrictMode Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Using strict hex checking (even length required)..." & @CRLF) ; Strict mode: ALL hex must have even length ; Check hex with prefix: 0x + even number of hex digits Local $sStrictHexWithPrefixPattern = "^0[xX][0-9A-Fa-f]+$" If StringRegExp($vInput, $sStrictHexWithPrefixPattern) Then ; Check if hex part (after 0x) has even length Local $sHexPart = StringMid($vInput, 3) ; Remove "0x" or "0X" If Mod(StringLen($sHexPart), 2) = 0 Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Hex with prefix has even length (" & StringLen($sHexPart) & ") -> Valid" & @CRLF) $bIsHex = True Else If $bShowDebug Then ConsoleWrite("- [DEBUG] Hex with prefix has odd length (" & StringLen($sHexPart) & ") -> Invalid" & @CRLF) EndIf EndIf ; Check hex without prefix: must be even length and at least 2 characters If Not $bIsHex Then Local $sStrictHexWithoutPrefixPattern = "^[0-9A-Fa-f]{2,}$" If StringRegExp($vInput, $sStrictHexWithoutPrefixPattern) And Mod(StringLen($vInput), 2) = 0 Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Hex without prefix has even length (" & StringLen($vInput) & ") -> Valid" & @CRLF) $bIsHex = True EndIf EndIf ; Debug info for failed strict hex If Not $bIsHex And $bShowDebug And StringRegExp($vInput, "^[0-9A-Fa-f]+$") Then ConsoleWrite("- [DEBUG] Valid hex characters but odd length (" & StringLen($vInput) & ") -> Invalid in strict mode" & @CRLF) EndIf Else If $bShowDebug Then ConsoleWrite("- [DEBUG] Using loose hex checking (any length allowed)..." & @CRLF) ; Loose mode: accept any valid hex format (any length) Local $sHexWithPrefixPattern = "^0[xX][0-9A-Fa-f]+$" Local $sHexWithoutPrefixPattern = "^[0-9A-Fa-f]+$" If StringRegExp($vInput, $sHexWithPrefixPattern) Or StringRegExp($vInput, $sHexWithoutPrefixPattern) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Hex pattern matched (any length) -> Valid" & @CRLF) $bIsHex = True EndIf EndIf ; Return hex result if found If $bIsHex Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: Hexadecimal string -> Binary/Hex (2)" & @CRLF) Return 2 EndIf ; ------------------------------------------------------------------------ ; ALL OTHER STRING TYPES RETURN 0 (including special detection for debug) ; ------------------------------------------------------------------------ If $bShowDebug Then If (StringStripWS($vInput, 8) == "") Then ConsoleWrite("- [DEBUG] Result: Empty string -> String Type (0)" & @CRLF) ElseIf StringRegExp($vInput, "^[a-zA-Z]:\\") Then ConsoleWrite("- [DEBUG] Result: Windows path detected -> String Type (0)" & @CRLF) ElseIf StringRegExp($vInput, "^https?://") Then ConsoleWrite("- [DEBUG] Result: URL detected -> String Type (0)" & @CRLF) ElseIf StringRegExp($vInput, "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") Then ConsoleWrite("- [DEBUG] Result: Email detected -> String Type (0)" & @CRLF) ElseIf StringRegExp($vInput, "^[0-9]+$") Then ConsoleWrite("- [DEBUG] Result: All digits string -> String Type (0)" & @CRLF) ElseIf StringRegExp($vInput, "^[a-zA-Z]+$") Then ConsoleWrite("- [DEBUG] Result: All alphabetic -> String Type (0)" & @CRLF) Else ConsoleWrite("- [DEBUG] Result: Generic string -> String Type (0)" & @CRLF) EndIf EndIf Return 0 EndIf ; ============================================================================ ; DEFAULT FOR UNKNOWN TYPES ; ============================================================================ If $bShowDebug Then ConsoleWrite("- [DEBUG] Result: Unknown type (-1)" & @CRLF) Return -1 EndFunc ;==>CheckDataType ; ============================================================================ ; HELPER FUNCTION FOR DEMO/TESTING ONLY (Not part of main functionality) ; ============================================================================ ; Helper function to convert result code to readable name for demo purposes Func GetDataTypeName($iCode) Switch $iCode Case 0 Return "String Type" Case 1 Return "Number Type" Case 2 Return "Binary/Hex Type" Case 4 Return "Boolean Type" Case 5 Return "Array" Case 6 Return "Map" Case 7 Return "Pointer" Case 8 Return "DLL Struct" Case 9 Return "Window Handle" Case 10 Return "Object" Case Else Return "Unknown (" & $iCode & ")" EndSwitch EndFunc ;==>GetDataTypeName ; === TEST EXAMPLES === ConsoleWrite("!=== COMPACT TYPE CHECKING RESULTS ===" & @CRLF) ; Test various data types including hex with different lengths Local $aTestValues[] = [123, 12.34, "123", "12.34", "Hello", "0xFF", "ABCD", "ABC", "A", "true", "false", "", _ "C:\Windows\System32", "https://www.google.com", "user@example.com", "12345", _ "1,234", "1.234", "1,234.56", "1.234,56", "1,234,567.89", "1.234.567,89", "12,5", _ "0xABC", "0xABCD", "F", "FF", "123ABC", "ABCDEF"] ConsoleWrite("+ Testing without debug (Loose mode):" & @CRLF) For $i = 0 To UBound($aTestValues) - 1 Local $result = CheckDataType($aTestValues[$i], False, False) ConsoleWrite("- '" & String($aTestValues[$i]) & "' -> " & GetDataTypeName($result) & " (" & $result & ")" & @CRLF) Next ConsoleWrite(@CRLF & "!=== DETAILED DEBUG FOR HEX CASES ===" & @CRLF) ; Test with debug for hex cases in both modes Local $debugTests[] = ["ABC", "ABCD", "0xABC", "0xABCD", "F", "FF"] For $i = 0 To UBound($debugTests) - 1 ConsoleWrite(@CRLF & "+ Debug test for '" & $debugTests[$i] & "' (Loose mode):" & @CRLF) Local $result = CheckDataType($debugTests[$i], False, True) ConsoleWrite("+ Debug test for '" & $debugTests[$i] & "' (Strict mode):" & @CRLF) Local $result2 = CheckDataType($debugTests[$i], True, True) Next ; === USAGE EXAMPLES === ConsoleWrite(@CRLF & "!=== USAGE EXAMPLES ===" & @CRLF) ; Test with actual AutoIt data types Local $myArray[3] = [1, 2, 3] Local $myMap[] $myMap["key"] = "value" ConsoleWrite("- Array: " & GetDataTypeName(CheckDataType($myArray)) & @CRLF) ConsoleWrite("- Map: " & GetDataTypeName(CheckDataType($myMap)) & @CRLF) ConsoleWrite("- Integer: " & GetDataTypeName(CheckDataType(42)) & @CRLF) ConsoleWrite("- Float: " & GetDataTypeName(CheckDataType(3.14159)) & @CRLF) ConsoleWrite("- String int: " & GetDataTypeName(CheckDataType("42")) & @CRLF) ConsoleWrite("- Hex loose: " & GetDataTypeName(CheckDataType("0xFF")) & @CRLF) ConsoleWrite("- Hex strict ABC: " & GetDataTypeName(CheckDataType("ABC", True)) & @CRLF) ConsoleWrite("- Hex strict ABCD: " & GetDataTypeName(CheckDataType("ABCD", True)) & @CRLF) ConsoleWrite("- Boolean true: " & GetDataTypeName(CheckDataType(True)) & @CRLF) ConsoleWrite("- String bool: " & GetDataTypeName(CheckDataType("true")) & @CRLF) ConsoleWrite("- International numbers: " & GetDataTypeName(CheckDataType("1,234.56")) & @CRLF) ConsoleWrite("- EU format: " & GetDataTypeName(CheckDataType("1.234,56")) & @CRLF) ConsoleWrite("- Thousands only: " & GetDataTypeName(CheckDataType("1,234")) & @CRLF) ioa747 1 Regards,
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now