Split large string - string

I have a long text which needs to be converted to small strings so I can include it to an AutoIt script. If I include multi-line text it shows error unterminated string. So I should have:
"numbercharswillbe10" &_ "othernumbersofcharwillbe10" &_ etc..
How can I split it with & _ -delimiters?

String concatenation
As per Documentation - Language Reference - Operators:
& Concatenates/joins two strings.
&= Concatenation assignment.
Example:
Global $g_sText = "Long " & "string " & "here." & #CRLF
$g_sText &= "More text." & #CRLF
ConsoleWrite($g_sText)
Multi line statements
As per Documentation - Language Reference - Comments (emphasis added, as it causes mentioned "unterminated string" error):
Although only one statement per line is allowed, a long statement can span multiple lines if an underscore "_" preceded by a blank is placed at the end of a "broken" line. String definition cannot be split in several lines, concatenation need to be used.
Example:
Global Const $g_sText = "Long " & _
"string " & _
"here." & _
#CRLF & _
"More text." & _
#CRLF
ConsoleWrite($g_sText)
Double-quotes
As per Documentation - FAQ - Double quotes:
If you want to use double-quotes inside a string then you must "double them up". So for every one quote you want you should use two. ...
or use single quotes instead ...
Examples available from source.
Defaults and limits
As per Documentation - Appendix - Limits/defaults:
4095 Maximum size for a line of script.
2,147,483,647 Maximum string length.
As per Documentation - Language Reference - Datatypes - Strings:
All AutoIt strings use UTF-16 (in fact and more precisely UCS-2) encoding.
As per Documentation - Intro - Unicode Support:
There are a few parts of AutoIt that don't yet have full Unicode support. These are:
Send and ControlSend - Instead, Use ControlSetText or the Clipboard functions.
Console operations are converted to ANSI.
Alternatives
Alternatives to hard coding include ClipGet() and FileRead().
Text from clipboard
Example (select and copy text CTRL + C first):
Global Const $g_sText = ClipGet()
ConsoleWrite($g_sText & #CRLF)
Text from file
Example (create C:\my_long_string.txt first):
#include <FileConstants.au3>
Global Const $g_sFile = 'C:\my_long_string.txt'
Global Const $g_sText = _TextFromFile($g_sFile)
ConsoleWrite($g_sText & #CRLF)
Func _TextFromFile(Const $sFile)
Local $hFile = FileOpen($sFile, $FO_READ + $FO_UTF8_NOBOM)
Local Const $sData = FileRead($hFile)
FileClose($hFile)
Return $sData
EndFunc
Split string
Alternatives to hard coded manual string splitting include StringSplit(), _StringExplode() (related) and StringMid().
Structural
StringSplit() splits a string into array of:
individual characters (on empty delimiter),
words (on space delimiter) or
lines (on #CRLF, #LF or #CR delimiter).
Equal length
StringMid() returns part of a string. Can be used to split into parts of equal length. Example (no error checking, select and copy text CTRL + C first):
#include <Array.au3>
Global Const $g_iSize = 10
Global Const $g_sText = ClipGet()
Global Const $g_aArray = _StringSplitEqual($g_sText, $g_iSize)
_ArrayDisplay($g_aArray)
Func _StringSplitEqual(Const $sText, Const $iSize = 1)
Local Const $iLength = StringLen($sText)
Local Const $iParts = Ceiling($iLength / $iSize)
Local Const $iRest = -1; $iLength - ($iSize * Floor($iLength / $iSize))
Local $iStart = 0
Local $iCount = 0
Local $aArray[$iParts]
For $i1 = 0 To $iParts - 1
$iStart = ($i1 * $iSize) + 1
$iCount = ($i1 < $iParts - 1) ? $iSize : ($iRest ? $iRest : $iSize)
$aArray[$i1] = StringMid($sText, $iStart, $iCount)
Next
Return $aArray
EndFunc
Join string
As per documentation:
_ArrayToStringPlaces the elements of a 1D or 2D array into a single string, separated by the specified delimiters
Example (add _StringSplitEqual() and select and copy text CTRL + C first):
#include <Array.au3>
Global Const $g_iSize = 10
Global Const $g_sStart = '$sText = "'
Global Const $g_sEnd = '"' & #CRLF
Global Const $g_sDelimiter = '" _' & #CRLF & ' & "'
Global Const $g_sText = StringReplace(ClipGet(), #CRLF, '')
Global Const $g_aArray = _StringSplitEqual($g_sText, $g_iSize)
Global $g_sResult = _ArrayToString($g_aArray, $g_sDelimiter)
$g_sResult = $g_sStart & $g_sResult & $g_sEnd
ConsoleWrite($g_sResult)
Returns:
$sText = "AutoIt v3 " _
& "is a freew" _
& "are BASIC-" _
& "like scrip" _
& "ting langu" _
& "age design" _
& "ed for aut" _
& "omating th" _
& "e Windows " _
& "GUI and ge" _
& "neral scri" _
& "pting."

Related

Multiline string literal in Ada

How can I create a string in Ada containing newlines, whose definition also has those newlines?
I've tried with 0..2 backslashes at the end of the line, but none of that compiles:
usage_info : String := "\
This should be the first line
and both the definition and the output
should contain newlines.";
In PHP this would be:
<<<BLOCK
1
2
3
BLOCK;
In C++ this would be:
const std::string s = "\
1
2
3";
In C#, it would be:
const string s =
#"1
2
3";
From what I know, Ada , like Java, does not support multiline literal.
The only thing I see is something like this:
usage_info : String := "This should be the first line" & CR & LF
& "and both the definition and the output" & CR & LF
& "should contain newlines.";
Of course, you need to with and use Ada.Characters.Latin_1 to make these constants visible.
A complement to Frédéric Praca answer:
Depending on your needs, you can use ASCII package instead of Ada.Characters.* (such as Latin_1, Latin_9, Wide_Latin_.. etc.). ASCII can not be with'ed since it is not a package, so you'll have to prefix everything (or define "aliases" using renames)
declare
flex : constant String := "Foo" & ASCII.CR & "bar" & ASCII.LF;
flux : constant String := "Foo" & ASCII.CR
& "bar" & ASCII.LF;
begin
-- do stuff
null;
end;
One could define a custom & operator to use it as a new line insertion point. But ... how useful is it ?
function Foo (Left, Right : String) return String renames "&";
function Boo (Left : String; Right : Character) return String renames "&";
function "&" (Left, Right : String) return String is begin
return Foo (
Boo (Left, ASCII.LF),
Right);
end "&";
Ada.Text_IO.Put_Line("Foo" &
"bar");

Can I make this AutoHotKey qwerty-half keyboard script work with caps-lock on?

I found this script at https://autohotkey.com/board/topic/1257-half-qwerty-one-handed-typing/
What this script does is it remaps the spacebar to be a modifier. When space is held, the keyboard is inverted, with the line of symmetry between g and h. Thus, e would become i, b would become n, p would become q, and so on. If the spacebar is depressed and released without pressing any other keys, a single space is sent. Modifier keys such as shift or control can be used in conjuction with Half-qwerty.
The problem is, it doesn't work for capital letters while caps lock is on.
Any help would be awesome!!
;QWERTY half-keyboard emulator
mirror_1 = 0
mirror_2 = 9
mirror_3 = 8
mirror_4 = 7
mirror_5 = 6
mirror_q = p
mirror_w = o
mirror_e = i
mirror_r = u
mirror_t = y
mirror_a = `;
mirror_s = l
mirror_d = k
mirror_f = j
mirror_g = h
mirror_z = /
mirror_x = .
mirror_c = ,
mirror_v = m
mirror_b = n
mirror_6 = 5
mirror_7 = 4
mirror_8 = 3
mirror_9 = 2
mirror_0 = 1
mirror_y = t
mirror_u = r
mirror_i = e
mirror_o = w
mirror_p = q
mirror_h = g
mirror_j = f
mirror_k = d
mirror_l = s
mirror_n = b
mirror_m = v
;This key may help, as the space-on-up may get annoying, especially if you type fast.
Control & Space::Suspend
;These keys are optional, but they may help if you are typing on the left-hand side.
CapsLock::Send, {BackSpace}
+Capslock::Capslock
;Capslock is backspace and Shift+Capslock works for Capslock.
Space & `::Send, {-}
Space & CapsLock::Send, {Enter}
If spacebar didn't modify anything, send a real space keystroke upon release.
space::
Send {space}
return
space & 1::
space & 2::
space & 3::
space & 4::
space & 5::
space & q::
space & w::
space & e::
space & r::
space & t::
space & a::
space & s::
space & d::
space & f::
space & g::
space & z::
space & x::
space & c::
space & v::
space & b::
space & `;::
space & ,::
space & .::
space & /::
space & 6::
space & 7::
space & 8::
space & 9::
space & 0::
space & y::
space & u::
space & i::
space & o::
space & p::
space & h::
space & j::
space & k::
space & l::
space & n::
space & m::
;Determine the mirror key, if there is one:
if A_ThisHotkey = space & `;
MirrorKey = a
else if A_ThisHotkey = space & ,
MirrorKey = c
else if A_ThisHotkey = space & .
MirrorKey = x
else if A_ThisHotkey = space & /
MirrorKey = z
else ; To avoid runtime errors due to invalid var names, do this part last.
{
StringRight, ThisKey, A_ThisHotkey, 1
StringTrimRight, MirrorKey, mirror_%ThisKey%, 0 ; Retrieve "array" element.
if MirrorKey = ; No mirror, script probably needs adjustment.
return
}
Modifiers =
GetKeyState, state1, LWin
GetKeyState, state2, RWin
state = %state1%%state2%
if state <> UU ; At least one Windows key is down.
Modifiers = %Modifiers%#
GetKeyState, state1, Control
if state1 = D
Modifiers = %Modifiers%^
GetKeyState, state1, Alt
if state1 = D
Modifiers = %Modifiers%!
GetKeyState, state1, Shift
if state1 = D
Modifiers = %Modifiers%+
Send %Modifiers%{%MirrorKey%}
return
Note that AutoHotKey variable names are NOT case sensitive.
; Associative array that mirrors the left and right side of the keyboard.
keyA := {"1" : "0"
,"2" : "9"
,"3" : "8"
,"4" : "7"
,"5" : "6"
,"q" : "p"
,"w" : "o"
,"e" : "i"
,"r" : "u"
,"t" : "y"
,"a" : ";"
,"s" : "l"
,"d" : "k"
,"f" : "j"
,"g" : "h"
,"z" : "/"
,"x" : "."
,"c" : ","
,"v" : "m"
,"b" : "n"
,"0" : "1"
,"9" : "2"
,"8" : "3"
,"7" : "4"
,"6" : "5"
,"p" : "q"
,"o" : "w"
,"i" : "e"
,"u" : "r"
,"y" : "t"
,";" : "a"
,"l" : "s"
,"k" : "d"
,"j" : "f"
,"h" : "g"
,"/" : "z"
,"." : "x"
,"," : "c"
,"m" : "v"
,"n" : "b"}
; Make Hotkeys
for index, value in keyA
Hotkey, % "$*" index, FlipFlop, On
return
; Disables space from being sent if it's held down for more than 300ms
$*Space::
KeyWait, Space, T0.3
if (ErrorLevel = 1)
KeyWait, Space
Else
Send, {Space}
return
; Removes the hook and wildcard modifiers
FlipFlop:
StringReplace, hk, A_ThisHotkey, % "$*"
; If space is held
if GetKeyState("Space", "P")
; Send the mirror of the keys along with any held modifiers
Send, % "{Blind}" keyA[hk]
Else
; Send the actual key pressed along with modifiers
Send, % "{Blind}" hk
return
Use an associative Array instead off mirror_a etc. and include the capital letters as well.

VBScript string replace with range instead of string?

Replace() already exists, but that function takes strings as parameters. I need range.
In my string there are two "strings" that are 10 characters long.
Greger with 6 chars and 4 spaces and the other string with 10 characters.
"Greger AASSDDFFGG"
I want to replace "Greger " with "googlioa "
What i'm looking for is basically this:
Replace(MyString,1,10) = "googlioa "
Is there any way to achieve this?
If they're always going to be 10 chars, just pad the names.
strNameFind = "Greger"
strNameReplace = "googlioa"
' Pad the names...
strNameFind = Left(strNameFind & Space(10), 10)
strNameReplace = Left(strNameReplace & Space(10), 10)
MyString = Replace(MyString, strNameFind, strNameReplace)
Alternatively, if you don't want to determine the existing name, just pad your new name appropriately and add the remainder of your string:
' Pad the new name to fit in a 10-char column...
strNameReplace = "googlioa"
strNameReplace = Left(strNameReplace & Space(10), 10)
' Update the record...
MyString = strNameReplace & Mid(MyString, 11)
If you want to replace strictly by position, use concatenation of Left(), new, and Mid(). To get you started:
>> Function replByPos(s, f, l, n)
>> replByPos = Left(s, f-1) & n & Mid(s, f + l - 1)
>> End Function
>> s = "Greger AASSDDFFGG"
>> r = replByPos(s, 1, 10, "googlioa ")
>> WScript.Echo s
>> WScript.Echo r
>>
Greger AASSDDFFGG
googlioa AASSDDFFGG
>>
Further enhancements:
safety: f(rom) - 1 is risky - should be checked
padding of new string wrt l(ength)
perhaps you want to search (Instr()) for old ("Greger ") before the concatenation
On second thought (and stealing Bond's padding):
Maybe I should have interpeted the 10 as a to/till/upto value instead of a length/width specification. So see whether
Option Explicit
Function replByPos(src, from, till, ns)
Dim w : w = till - from
replByPos = Left(src, from - 1) & Left(ns & Space(w), w) & Mid(src, till)
End Function
Dim s : s = "Greger AASSDDFFGG"
Dim ns : ns = "googlioa"
WScript.Echo s
WScript.Echo replByPos(s, 1, 10, ns)
s = "Whatever Greger AASSDDFFGG"
ns = "googlioa"
Dim p : p = Instr(s, "Greger")
WScript.Echo s
WScript.Echo replByPos(s, p, p + 10, ns)
output:
cscript 22811896.vbs
Greger AASSDDFFGG
googlioa AASSDDFFGG
Whatever Greger AASSDDFFGG
Whatever googlioa AASSDDFFGG
matches your specs better.

Replace Characters in a string except values inside double quote

I want to replace an array of characters with empty space except values inside double quote in a string.
Example
"India & China" relationship & future development
In the above example, I need to replace & but thats not inside any of the double quotes(""). The expected result should be
Result
"India & China" relationship future development
Other Examples of String
relationship & future development "India & China" // Output: relationship future development "India & China"
"relationship & future development India & China // Output: reflect the same input string as result string when the double quote is unclosed.
I have so far done the below logic to replace the characters in a string.
Code
string invalidchars = "()*&;<>";
Regex rx = new Regex("[" + invalidchars + "]", RegexOptions.CultureInvariant);
string srctxtaftrep = rx.Replace(InvalidTxt, " ");
RegexOptions options = RegexOptions.None;
Regex regex = new Regex(#"[ ]{2,}", options);
srctxtaftrep = regex.Replace(srctxtaftrep, #" ");
InvalidTxt = srctxtaftrep;
Here's a non-regex approach using a StringBuilder which should work:
string input = "\"India & China\" relationship & future development";
HashSet<char> invalidchars = new HashSet<char>("()*&;<>");
StringBuilder sb = new StringBuilder();
bool inQuotes = false;
foreach(char c in input)
{
if(c == '"') inQuotes = !inQuotes;
if ((inQuotes && c != '"') || !invalidchars.Contains(c))
sb.Append(c);
}
string output = sb.ToString();

How to insert a space every two characters?

I would like to split byte strings, for example AAFF10DC, with spaces, so it becomes AA FF 10 DC.
How to do this in AutoIt (v3)?
I would like to split byte strings … with spaces …
Example using StringRegExpReplace() :
Global Const $g_sString = 'AAFF10DC'
Global Const $g_sPattern = '(.{2})'
Global Const $g_sReplace = '$1 '
Global Const $g_sResult = StringRegExpReplace($g_sString, $g_sPattern, $g_sReplace)
ConsoleWrite($g_sResult & #CRLF)
Returns AA FF 10 DC.
This is sorta ugly, but it works:
$string = "AAFF10DC"
$strArray = StringSplit($string, "") ; No delimiter will separate all chars.
$strResult = ""
If IsEvenNumber($strArray[0]) Then
For $i = 1 to $strArray[0] Step 2
$strResult = $strResult & $strArray[$i] & $strArray[$i+1] & " "
Next
MsgBox(0, "Result", $strResult)
Else
MsgBox(0, "Result", "String does not contain an even number of characters.")
EndIf
Func IsEvenNumber($num)
Return Mod($num, 2) = 0
EndFunc
Global $s_string = "AAFF10DC"
MsgBox(64, "Info", _str_bytesep($s_string))
Func _str_bytesep($s_str, $s_delim = " ")
If Not (Mod(StringLen($s_str), 2) = 0) Then Return SetError(1, 0, "")
Return StringRegExpReplace($s_str, "(..(?!\z))", "$1" & $s_delim & "")
EndFunc
Is just another way to do it. For huge amounts of byte data, I would not suggest using this method.

Resources