Jump to content

Recommended Posts

Posted (edited)

Whenever I embed strings in code that contain quotes I have to separate them very carefully,

so I wrote this function to do it automatically correctly:

#include <Array.au3>

; ============================================================================
; Function : _MakeValidString
; Purpose  : Convert a string containing both single (') and double (") quotes
;            into a valid AutoIt expression by splitting it into segments,
;            wrapping each segment in the opposite quote type, and joining
;            them with the concatenation operator (&).
; Author:   Dao Van Trong - TRONG.PRO
; Parameters:
;     $s (String) – The original input string that may include ' and " characters.
; Returns:
;     (String) – A valid AutoIt expression where each segment is properly quoted 
;                  and concatenated so that embedded quotes are handled correctly.
; Example:
;     Local $raw    = "A'" & "BC'" & 'DE"' & "F"
;     Local $result = _MakeValidString($raw)
;     -> $result = "A'" & "BC'" & 'DE"' & "F"
; ============================================================================

Func _MakeValidString($s)
    ; Create a dynamic array to hold each quoted segment
    Local $aParts[0]

    While StringLen($s) > 0
        ; Find the first occurrence of single-quote and double-quote
        Local $iPosSingle = StringInStr($s, "'")
        Local $iPosDouble = StringInStr($s, '"')

        ; If no more quotes are found, wrap the remainder in double-quotes and exit
        If Not $iPosSingle And Not $iPosDouble Then
            _ArrayAdd($aParts, '"' & $s & '"')
            ExitLoop
        EndIf

        ; Determine which quote occurs first
        If $iPosSingle = 0 Or ($iPosDouble <> 0 And $iPosDouble < $iPosSingle) Then
            $iEarliest = $iPosDouble
        Else
            $iEarliest = $iPosSingle
        EndIf

        ; Extract the segment up to and including that quote
        Local $sSegment = StringLeft($s, $iEarliest)

        ; Wrap the segment:
        ; - If it contains a single-quote, use double-quotes around it
        ; - Otherwise, use single-quotes
        If StringInStr($sSegment, "'") Then
            $sSegment = '"' & $sSegment & '"'
        Else
            $sSegment = "'" & $sSegment & "'"
        EndIf

        ; Add the wrapped segment to our array
        _ArrayAdd($aParts, $sSegment)

        ; Remove the processed part and continue
        $s = StringMid($s, $iEarliest + 1)
    WEnd

    ; Concatenate all parts with the & operator
    Return _ArrayToString($aParts, " & ")
EndFunc

No Array:

; ============================================================================
; Function : _MakeValidString
; Purpose  : Convert a string containing both single (') and double (") quotes
;            into a valid AutoIt expression by splitting it into segments,
;            wrapping each segment in the opposite quote type, and joining
;            them with the concatenation operator (&).
; Author   : Dao Van Trong - TRONG.PRO
; Parameters:
;     $sInput (String) – Original string that may include ' and ".
; Returns:
;     (String) – A valid AutoIt expression with each segment properly quoted
;                 and concatenated.
; Example:
;~          Local $raw = "A'" & "BC'" & 'DE"' & "F"
;~          Local $result = _MakeValidString($raw)
;~          ConsoleWrite($result & @CRLF)
; ============================================================================

Func _MakeValidString($sInput)
    Local $sResult     = ""      ; Final concatenated expression
    Local $bIsFirst    = True    ; Flag for inserting " & " between parts

    While StringLen($sInput) > 0
        ; Find positions of the next single-quote and double-quote
        Local $posSingle = StringInStr($sInput, "'")
        Local $posDouble = StringInStr($sInput, '"')

        ; If no quotes remain, wrap the rest in double-quotes and finish
        If Not $posSingle And Not $posDouble Then
            Local $segment = '"' & $sInput & '"'
            If Not $bIsFirst Then $sResult &= " & "
            $sResult &= $segment
            ExitLoop
        EndIf

        ; Determine which quote appears first
        If $posSingle = 0 Or ($posDouble <> 0 And $posDouble < $posSingle) Then
            $iEarliest = $posDouble
        Else
            $iEarliest = $posSingle
        EndIf

        ; Extract substring up to and including that quote
        Local $sub = StringLeft($sInput, $iEarliest)

        ; Wrap in opposite quote type
        If StringInStr($sub, "'") Then
            $sub = '"' & $sub & '"'
        Else
            $sub = "'" & $sub & "'"
        EndIf

        ; Append to result with concatenation operator if needed
        If Not $bIsFirst Then $sResult &= " & "
        $sResult &= $sub

        ; Remove processed part and continue
        $sInput    = StringMid($sInput, $iEarliest + 1)
        $bIsFirst  = False
    WEnd

    Return $sResult
EndFunc

 

Edited by Trong

Regards,
 

Posted

Are you aware that you can escape the respective quote characters in AutoIt string definitions by simply doubling them?

So to create an AutoIt-compliant string definition for the AutoIt code itself from a string, you do not need to split it into individual strings and reassemble them, but simply double the quotes. This would be shorter, probably clearer and also better performing.

In concrete terms, the following should also achieve your actual goal

$result = '"' & StringReplace($raw, '"', '""', 0, 1) & '"'

; or equally:

$result = "'" & StringReplace($raw, "'", "''", 0, 1) & "'"

 

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...