Trong Posted Sunday at 09:58 PM Posted Sunday at 09:58 PM (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: expandcollapse popup#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: expandcollapse popup; ============================================================================ ; 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 Sunday at 11:56 PM by Trong Regards,
AspirinJunkie Posted Monday at 05:31 AM Posted Monday at 05:31 AM 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) & "'" SOLVE-SMART and Andreik 1 1
Trong Posted 59 minutes ago Author Posted 59 minutes ago (edited) Thanks for pointing out that simple way. Have you tried running and seeing the example result? It's also meant to make the code more confusing ^^. Anyway, it's complicated (I mean simple) so let's use this function: expandcollapse popupFunc _MakeValidString($sInput) ; Configuration: change these as needed Local $maxLen = 1000 ; max characters per generated line Local $indent = " " ; indent for continued lines ; State variables Local $result = "" ; final expression Local $buffer = "" ; accumulates normal chars Local $isFirst = True ; true until we add the first segment Local $lineLen = 0 ; length of the current line Local $inputLen = StringLen($sInput) Local $i = 1 While $i <= $inputLen Local $ch = StringMid($sInput, $i, 1) Local $next = ($i < $inputLen) ? StringMid($sInput, $i + 1, 1) : "" ;------------------------------- ; Flush buffer helper ;------------------------------- If $buffer <> "" Then Local $lit = '"' & $buffer & '"' Local $prefix = $isFirst ? "" : " & " Local $toAdd = $prefix & $lit If Not $isFirst And ($lineLen + StringLen($toAdd) > $maxLen) Then ; break the line $result &= " & _" & @CRLF & $indent & $lit $lineLen = StringLen($indent) + StringLen($lit) Else $result &= $toAdd $lineLen += StringLen($toAdd) EndIf $isFirst = False $buffer = "" EndIf ;------------------------------- ; Handle CRLF ;------------------------------- If $ch = @CR And $next = @LF Then Local $seg = "@CRLF" Local $prefix = $isFirst ? "" : " & " Local $toAdd = $prefix & $seg If Not $isFirst And ($lineLen + StringLen($toAdd) > $maxLen) Then $result &= " & _" & @CRLF & $indent & $seg $lineLen = StringLen($indent) + StringLen($seg) Else $result &= $toAdd $lineLen += StringLen($toAdd) EndIf $isFirst = False $i += 2 ContinueLoop EndIf ;------------------------------- ; Handle LF, CR, TAB ;------------------------------- If $ch = @LF Or $ch = @CR Or $ch = @TAB Then Local $seg = ($ch = @LF) ? "@LF" _ : ($ch = @CR) ? "@CR" _ : "@TAB" Local $prefix = $isFirst ? "" : " & " Local $toAdd = $prefix & $seg If Not $isFirst And ($lineLen + StringLen($toAdd) > $maxLen) Then $result &= " & _" & @CRLF & $indent & $seg $lineLen = StringLen($indent) + StringLen($seg) Else $result &= $toAdd $lineLen += StringLen($toAdd) EndIf $isFirst = False $i += 1 ContinueLoop EndIf ;------------------------------- ; Handle non-ASCII (Unicode) ;------------------------------- If Asc($ch) > 127 Then Local $seg = "ChrW(" & Asc($ch) & ")" Local $prefix = $isFirst ? "" : " & " Local $toAdd = $prefix & $seg If Not $isFirst And ($lineLen + StringLen($toAdd) > $maxLen) Then $result &= " & _" & @CRLF & $indent & $seg $lineLen = StringLen($indent) + StringLen($seg) Else $result &= $toAdd $lineLen += StringLen($toAdd) EndIf $isFirst = False $i += 1 ContinueLoop EndIf ;------------------------------- ; Normal character or internal double-quote ;------------------------------- If $ch = '"' Then $buffer &= '""' Else $buffer &= $ch EndIf $i += 1 WEnd ; Final flush of any remaining buffer If $buffer <> "" Then Local $lit = '"' & $buffer & '"' Local $prefix = $isFirst ? "" : " & " Local $toAdd = $prefix & $lit If Not $isFirst And ($lineLen + StringLen($toAdd) > $maxLen) Then $result &= " & _" & @CRLF & $indent & $lit Else $result &= $toAdd EndIf EndIf Return $result EndFunc or Your code: Func _MakeValidString($sInput) Return '"' & StringReplace($sInput, '"', '""') & '"' EndFunc l Edited 26 minutes ago by Trong add code 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