Stringx.au3

Last modified:   Sunday, 14 June 2009

;*******************************************************************************
;
;   Function List
;         __HexToString()
;         __StringToHex()
;         _StringAddThousandsSep()
;         _String_CreateWordList()
;         _String_GetChrCount()
;         _String_GetQuotes()
;         _String_GetWord()
;         _StringIsLower()
;         _StringIsUpper()
;         _String_LastIndexOf()
;         _String_WordOccurs()
;
;*******************************************************************************

#include-once

;===============================================================================
; Function Name:    __HexToString()
; Description:      Convert a Hex value to a string value
; Syntax:           __HexToString($sString)
; Parameter(s):     $sHex - The Hex value to convert
; Requirements:      None
; Return Value(s):  Success - Returns the String representation of $sHex
; Author(s):        SmOke_N
; Modifications:
; Notes:
; Example(s):     MsgBox(0, 'Test', $sHex & @CRLF & __HexToString("5468697320697320736F6D652074657874"))
;===============================================================================

Func __HexToString($sString)
  If StringLeft($sString, 2) <> "0x"Then
    $sString = "0x" & $sString
  EndIf
  Return BinaryToString($sString)
EndFunc   ;<==> __HexToString()

;===============================================================================
; Function Name:   __StringToHex()
; Description:   Convert a string to a Hex value
; Syntax:   
; Parameter(s):   $sString - The string to convert
; Requirement(s):   
; Return Value(s):   The hex value of the input string
; Author(s):   George (GEOSoft) Gedye
; Modification(s):   
; Note(s):   
; Example(s): 
;===============================================================================

Func __StringToHex($sString)
  Return StringTrimLeft(StringToBinary($sString), 2)
EndFunc   ;<==> __StringToHex()


;===============================================================================
; Function Name:   _StringAddThousandsSep()
; Description:     Returns the original numbered string with the Thousands and or Decimal delimiter(s) inserted.
; Syntax:          _StringAddThousandsSep($s_string[, $i_convert_lcid = -1[, $i_current_lcid = -1]])
; Parameter(s):    $s_string         - The string to be converted.
;                  $i_convert_lcid   - Optional: Default or -1 wll be the User default locale else:
;                   |LCID of what you want to convert number to.
;                  $i_current_lcid   - Optional: Default or -1 wll be the User default locale else:
;                   |LCID number was converted with originally.
; Requirement(s):  
; Return Value(s): - Success - The string with Thousands delimiter added.
;                  - Failure - Returns empty string and sets @error to 1.
; Author(s):       SmOke_N (orignal _StringAddComma); Valik (original _StringAddThousandsSep)
;                  GEOSoft (added localaization and ability to handle pre-formatted strings)
;                  SmOke_N (complete re-write)
; Modification(s): 
; Note(s):    Changes are script breaking after AutoIt version 3.3.0.0
;             LCID numbers can be obtained by pre-pending the OSLang codes in the help file appendix with "0x".
;             This will be the LAST re-write of this function.  DO NOT ask for further changes.
;              If it's not returning what you want then write your own.
; Example(s):   
#cs

#ce
;===============================================================================

Func _StringAddThousandsSep($s_string, $i_convert_lcid = -1, $i_current_lcid = -1)
   ; $LOCALE_USER_DEFAULT = 0x0400
    If $i_current_lcid = -1 Or $i_current_lcid = Default Then $i_current_lcid = 0x0400
    If $i_convert_lcid = -1 Or $i_convert_lcid = Default Then $i_convert_lcid = 0x0400

   ; Get lcid decimal and thousands separators
    Local $t_buff_tmp = DllStructCreate("char[4]")
    DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_current_lcid, _
        "int", 0x0E, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4)
    If @error Then Return SetError(1, 0, "")
    Local $s_cur_dec = DllStructGetData($t_buff_tmp, 1)

    DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_convert_lcid, _
        "int", 0x0E, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4)
    If @error Then Return SetError(1, 0, "")
    Local $s_con_dec = DllStructGetData($t_buff_tmp, 1)

    DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_convert_lcid, _
        "int", 0x0F, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4)
    If @error Then Return SetError(1, 0, "")
    Local $s_con_tho = DllStructGetData($t_buff_tmp, 1)

   ; For later formatting
    Local $i_number = StringRegExpReplace($s_string, "(\" & $s_cur_dec & "\d+\z)|(^-|\d+)|(\D)", "$2")
    Local $i_dec = StringRegExpReplace($s_string, "(.+?\" & $s_cur_dec & ")(\d+\z)", "$2")
    If @extended = 0 Then $i_dec = ""

    Local $i_str_len = StringLen($s_string) * 4
    Local $t_numberfmt = DllStructCreate("uint;uint;uint;ptr;ptr;uint")
    Local $t_thousands = DllStructCreate("wchar[2]")
    Local $t_decimal = DllStructCreate("wchar[2]")
    Local $t_buffer = DllStructCreate("wchar[" & $i_str_len & "]")

    DllStructSetData($t_thousands, 1, $s_con_tho)
    DllStructSetData($t_decimal, 1, $s_con_dec)
    DllStructSetData($t_numberfmt, 3, 3)
    DllStructSetData($t_numberfmt, 4, DllStructGetPtr($t_decimal))
    DllStructSetData($t_numberfmt, 5, DllStructGetPtr($t_thousands))
    DllStructSetData($t_numberfmt, 6, 1)

    DllCall("kernel32.dll", "int", "GetNumberFormatW", _
        "int", $i_convert_lcid, "int", 0, _
        "wstr", $i_number, "ptr", DllStructGetPtr($t_numberfmt), _
        "ptr", DllStructGetPtr($t_buffer), "int", $i_str_len)

    If $i_dec = "" Then $s_con_dec = ""
    Return DllStructGetData($t_buffer, 1) & $s_con_dec & $i_dec
EndFunc   ;<==> _StringAddThousandsSep()

;===============================================================================
; Function Name:   _String_CountLines()
; Description:     Return the number of lines in text or file
; Syntax:          _String_CountLines("Text or full path to file")
; Parameter(s):    $sText - text or file to check
; Requirement(s):  
; Return Value(s): - Success Returns the line count of $sText
;                  - Failure set @Error to 1 if no text was passed to the function
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    
; Example(s):   
#cs
   $Count = _String_CountLines($sFile)
   MsgBox(0, "Line Count", $Count & " Lines")
#ce
;===============================================================================

Func _String_CountLines($sText)
   If FileExists($sText) Then $sText = FileRead($sText)
   If NOT $sText Then Return SetError(1)
   StringRegExpReplace($sText, "(?m:^).*\v|\z", "$1")
   Return @Extended
EndFunc   ;<==> _String_CountLines()

;===============================================================================
; Function Name:   _String_CreateWordList()
; Description:     Create an array of words in a string
; Syntax:          _String_CreateWordList("String or file"[, skip single letters]) 
; Parameter(s):    $sStr = String or file to check.
;                  $iSkip = Skip single character words. Default is Don't skip
; Requirement(s):  
; Return Value(s): - Success a 0 based array of all the words in a string
;                  - Failure 
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    best if this is used with _ArrayUnique() to get unique words
; Example(s):   
#cs
   $aArray = _String_CreateWordList("This is some test string of 10 words I put together",1)
   If Not @Error Then
      For $i = 0 To Ubound($aArray) -1
         MsgBox(4096,"Results", "Word number " & $i+1 & " is " & $aArray[$i])
      Next
   EndIf
#ce
;===============================================================================

Func _String_CreateWordList($sStr, $iSkip = 0)
   If FileExists($sStr) Then $sStr = FileRead($sStr)
   Local $sLen = "+"
   If $iSkip <> 0 Then $sLen = "{2,}"
   $aRegEx = StringRegExp($sStr, "(?i)\b([[:alpha:]]" & $sLen & ")\b", 3)
   If NOT @Error Then Return $aRegEx
   Return SetError(1) ;; Unable to create the array
EndFunc   ;<==> _String_CreateWordList()

;===============================================================================
; Function Name:   _String_GetChrCount()
; Description:   Count the number of times a given character appears in a string
; Syntax:   
; Parameter(s):   $cStr - The string to check
;                 $cChr - The character to count
;
; Requirement(s):   
; Return Value(s):   The number of times a character appears in a string
; Author(s):   George (GEOSoft) Gedye
; Modification(s):   
; Note(s):   Can also be used to determine how many times a string appears in a file
;             by using FileRead() for $cStr and the string for $cChar
;Example(s): 
#cs
   $Test = _String_GetChrCount("This is just an example.", Chr(32))
   MsgBox(0, "Results", $Test)
#ce
;             Since Chr(32) is a space then it would return 4
;===============================================================================

Func _String_GetChrCount($cStr, $cChr, $iCase = 0)
  If $iCase <> 0 Then $iCase = 1
  StringReplace($cStr, $cChr, $cChr, 0, $iCase)
  Return @Extended
EndFunc   ;<==> _String_GetChrCount()

;===============================================================================
; Function Name:   _String_GetQuotes()
; Description:     Find The Literal Strings And Set the Quotes
; Syntax:          
; Parameter(s):    $sString - The string to check
; Requirement(s):   
; Return Value(s): 
; Author(s):   Smoke_N
; Modification(s): 
; Note(s):    
; Example(s):   
;===============================================================================

Func _String_GetQuotes()
  ;Create delimiters for double single and double quotes 
  Local $sDQ = Chr(1) & Chr(1), $sSQ = Chr(3) & Chr(3) 
  ;Replace Double Double quotes "" 
  $sString = StringReplace($sString, '""', $sDQ) 
  ;Replace Double Single quote '' and return 
  $sString = StringReplace($sString, "''", $sSQ) 
  ;Get Quotes 
  Local $aSRE = StringRegExp($sString, '(?s)(".*?")|' & "('.*?')", 3) 
  If IsArray($aSRE) = 0 Then Return SetError(1, 0, "") 
  ;Loop through and add back in the correct quotes 
  For $iCC = 0 To UBound($aSRE) - 1 
    $aSRE[$iCC] = StringReplace($aSRE[$iCC], $sDQ, '""') 
    $aSRE[$iCC] = StringReplace($aSRE[$iCC], $sSQ, "''") 
  Next ;$iCC 
  Return $aSRE 
EndFunc   ;<==> _String_GetQuotes()

;===============================================================================
; Function Name:    _String_GetWord()
; Description:      Return a desired word from a string
; Syntax:           _String_GetWord($iStr, $rWrd)
; Parameter(s):     $iStr - The string to check
;                   $rWrd - The string location of the word you want to return (default is the first word)
; Requirements:      None
; Return Value(s):  Success - The word that appears in the location specified in $rWord
;                   Failure - Returns a blank string
; Author(s):        GEOSoft  - Modified from a function in JdeBs original Tidy script
; Modifications:    Added the ability to use StringRegEx compliments of Smoke_N
; Notes:
; Example(s):  MsgBox(0, 'Test', _String_GetWord("This is the string to test", 4))
;                          - will return the word "string"
;===============================================================================

Func _String_GetWord($iStr, $rWrd = 1, $Regx = 1)
  Local $aStr, $Rtn = ''
  If NOT $Regx Then
    $aStr = StringSplit (StringStripWS ($iStr, 3), " (" & @TAB)
    If $rWrd > $aStr[0] OR $rWrd < 1 Then Return $Rtn ;;<<=== You looked for value outside the array range
    If $aStr[0] > 0 Then
      If StringInStr ($aStr[1], '#', 0, 2) > 1 Then
        $aStr[1] = StringLeft ($aStr[1], StringInStr ($aStr[1], '#', 0, 2) - 1)
        If $rWrd = 1 Then Return ($aStr[1])
      EndIf
      $Rtn = ($aStr[$rWrd])
    EndIf
  Else
    $aStr = StringRegExp($iStr, "[\s\.:;,\?\!]*([a-zA-Z0-9-_#$=]+)[\s\.:;,\?\!]*", 3) 
    If IsArray($aStr) = 0 Then Return SetError(1, 0, "") 
    If $rWrd = 1 Then Return $aStr[0] 
    If $rWrd > UBound($aStr) Then Return SetError(2, 0, "") 
    $Rtn = $aStr[$rWrd - 1]
  EndIf
  Return $Rtn
EndFunc    ;<===> _String_GetWord()

;===============================================================================
; Function Name:   _StringIsLower()
; Description:     Check to make sure a string is all lower case
; Syntax:          _StringIsLower("string")
; Parameter(s):    $sStr - String to check
; Requirement(s):  
; Return Value(s): - Success = True if string is all lower case otherwise False
;                  - Failure 
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    This is used to avoid flicker problems when checking a GUI control
;             in a loop where the control contains punctuation or whitespace.
; Example(s):   
#cs
   _StringIsLower("This test sTring"); Returns False
   _StringIsLower("this test string."); Returns True
#ce
;===============================================================================

Func _StringIsLower()
   If StringRegExp($sStr,"[[:upper:]]") Then Return False
   Return True
EndFunc   ;<==> _StringIsLower()

;===============================================================================
; Function Name:   _StringIsUpper()
; Description:     Check to make sure a string is all UPPER case
; Syntax:          
; Parameter(s):    $sStr - String to check
; Requirement(s):  
; Return Value(s): - Success = True if string is all upper case otherwise False
;                  - Failure 
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    This is used to avoid flicker problems when checking a GUI control
;             in a loop where the control contains punctuation or whitespace.
; Example(s):   
#cs
   _StringIsUpper("THIS TeST STRiNG"); Returns False
   _StringIsUpper("THIS TEST STRING."); Returns True
#ce
;===============================================================================

Func _StringIsUpper($sStr)
   If StringRegExp($sStr,"[[:lower:]]") Then Return False
   Return True
EndFunc   ;<==> _StringIsUpper()

;===============================================================================
; Function Name:   _String_LastIndexOf()
; Description:   locate the last position in a string of a given character
; Syntax:   
; Parameter(s):   $liStr - The string to check
;                 $liChr - The character to locate
; Requirement(s):   
; Return Value(s):   The position in the string where the last $liChr is found
; Author(s):   George (GEOSoft) Gedye
; Modification(s):   
; Note(s):   This function is an AutoIt replacement for the VB LastIndexOf().
; Example(s): $Test = LastIndexOf("C:\test\myfile.txt", "\")
;             returns 8
;===============================================================================

Func _String_LastIndexOf($liStr, $liChr)
  Local $Li
  $Li = StringInStr($liStr, $liChr, 0, -1)
  Return $Li
EndFunc   ;<==> _String_LastIndexOf()

;===============================================================================
; Function Name:   _String_LineLength()
; Description:     Get longest or shortest lines in the text
; Syntax:          
; Parameter(s):    $sText - text or file to check
;                  $iLong - If set to -1 or default then it works with the longest line
;                              otherwise it uses the shortest line
;                  $iCount - If set to -1 or default then it returns the character count
;                              otherwise it returns the string
;                  $iArray - If NOT set to -1 or default then it returns an array where
;                              array[0] = the character count
;                              array[1] = the string
; Requirement(s):  
; Return Value(s): - Success 
;                  - Failure 
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    If $iArray is not either -1 or default then $iCount has no effect
; Example(s):   
#cs
   $sFile = @ScriptFullPath
   $Value = _String_LineLength($sFile,-1, 0)
   If NOT @Error Then
      If IsArray($Value) Then
         MsgBox(0, "Returned array", "Character Count = " & $Value[0] & @CRLF & @CRLF & $Value[1])
      Else
         MsgBox(0, "Length or string", $Value)
      EndIf
   EndIf
#ce
;===============================================================================

Func _String_LineLength($sText, $iLong = -1, $iCount = -1, $iArray = -1)
   If FileExists($sText) Then $sText = FileRead($sText)
   If NOT $sText Then Return SetError(1,1, "Unable to read the text")
   $aText = StringRegExp($sText, "(.*?)(?:\v|\z)", 3)
   If @Error Then Return SetError(1,2, "RegExpression Error")
   Local $iLength = StringLen($aText[0]), $sRtn = $aText[0]
   For $i = 1 To Ubound($aText) -1
      If NOT StringRegExp($aText[$i], "\s*\S") Then ContinueLoop
      If StringRegExp($iLong, "(?i)-1|default") Then
      If StringLen($aText[$i]) > $iLength Then
         $iLength = StringLen($aText[$i])
         $sRtn = $aText[$i]
      EndIf
      Else
      If StringLen($aText[$i]) < $iLength Then
         $iLength = StringLen($aText[$i])
         $sRtn = $aText[$i]
      EndIf
      EndIf
   Next
   If NOT StringRegExp($iArray, "(?i)-1|default") Then
      Local $aRtn[2]
      $aRtn[0] = $iLength
      $aRtn[1] = $sRtn
      Return $aRtn
   EndIf
   If StringRegExp($iCount, "(?i)-1|default") Then Return $iLength
   Return $sRtn
EndFunc   ;<==> _String_LineLength()

;===============================================================================
; Function Name:   _String_WordOccurs()
; Description:     Count the number of times that a word occurs in a string or file
; Syntax:          
; Parameter(s):    $sStr - String or File to search
;                  $sWord - The word to search for
;                  $iCase - Case sensitivity.  If -1 (default) then it's case sensitive
;                                              anything else = case insensitive
; Requirement(s):  
; Return Value(s): - Success = Returns the count
;                  - Failure = None
; Author(s):       George (GEOSoft) Gedye
; Modification(s): 
; Note(s):    
; Example(s):   
#cs
   $iCount = _String_WordOccurs("A test string to Test the count", "test")
   MsgBox(4096, "Results", "The word test occurs " & $iCount & " time(s).")
#ce
;===============================================================================

Func _String_WordOccurs($sStr, $sWord, $iCase = -1)
   If FileExists($sStr) Then $sStr = FileRead($sStr)
   Local $sCase = ""
   If $iCase <> -1 Then $sCase = "(?i)"
   StringRegExpReplace($sStr,$sCase & "\b(" & $sWord & ")\b", "$1")
   Return @Extended
EndFunc   ;<==> _String_WordOccurs()