I have a string that looks like this: [40,1,40,40,348,348,348,348,348,348, etc...]
Sometimes, when I generate this string, it is longer than 64,000 characters, so it is too long to save to a StringValue
. So I want to separate it into 64,000 character chunks so I can save it to several StringValue
s. How can I do this?
DigitalVeer's answer is useful for decoding the strings once you've loaded them, and TheDeadlyPanther has the right idea, just not quite the right algorithm:
function SplitIntoChunks(s, chunkSize) --s is the string, chunkSize is an integer. Returns a list of strings. local t = {} while #s > chunkSize do t[#t + 1] = s:sub(1, chunkSize) s = s:sub(chunkSize + 1) end t[#t + 1] = s return t end
You'll need to use the list of strings and distribute them to your StringValues. If you wanted to create a new StringValue for each entry, you might do:
local strings = SplitIntoChunks(originalString, 64000) for i = 1, #strings do local sValue = Instance.new("StringValue", workspace) sValue.Value = strings[i] end
To split a string up into different pieces, use string.sub
. It subdivides the string based on the information in the paramaters:
Parameter 1 = string, Parameter 2 = Position 1, Parameter 2 = Position 2 (defaults at the length of the string).
NOTE: Manipulation values can be done another way, instead of valuetype.action()
, that way isvalue:action()
(you don't need to specify what value you're indexing)
Using string.sub in this example would be hard, but this is what I've got:
local val1 = script.StringValue1 local s = [] local length = s:len() local num = 1 if length > 64000 then local clone = val:Clone() local clone2 = val:Clone() if length / 2 <= 64000 num = num + 1 clone.Parent = script clone.Name = "StringValue" ..num val1.Value = s:sub(1,length / 2 + 1) clone.Value = s:sub(length / 2 + 1,length) elseif length / 3 <= 6400 then num = num + 1 clone.Parent = script clone.Name = "StringValue" ..num val1.Value = s:sub(1,length / 3 + 1) clone.Value = s:sub(length / 3+ 1,length / 3 * 2) num = num + 1 clone2.Parent = script clone2.Name = "StringValue" ..num clone2.Value = s:sub(length / 3 * 2,length) end else val1.Value = s end
That should do it.
I think the best option here is to use some simple string matching! It's pretty easy with some basic patterns:
str = "[0,1,40,40,348,348,348,348,348,348]" for match in string.gmatch(str, "[^%[%],%s]+" ) do print(match) end
If you run the code, you'll see that only the numbers are printed. Allow me to explain the pattern:
Whenever you have something like this, [^ ]
, that is called a complement. Anything within the brackets that is after the ^
will be opposed. By this, I mean, the compiler will match everything isn't specified in the complement.
Since we see [
and ]
in your string, we certainly don't want these to be matched with the strings.
The thing is, brackets are special identifiers in string patterns that allow you to set things such as complements and sets. For this reason, we need to tell the compiler that we aren't closing the complement, but rather looking for anything that isn't [
or ]
. To do this, we just put a percent symbol %
preceding the brackets.
Pretty simple, we don't want to match commas either.
This is basically anything that is whitespace such as spaces and tabs. We want to ignore these so we add this special identifier to the complement
This is to match 1 or more
of the given pattern.
Our pattern basically says, "Match anything that isn't [ or ] or , or whitespace.
The reason we need the plus at the end is because if we left it out, only a single letter would be matched each time. So we want the longest possible sequence we can obtain.
Using this we can easily add support for making StringValues
str = "[0,1,40,40,348,348,348,348,348,348]" for match in string.gmatch(str, "[^%[%],%s]+" ) do local strV = Instance.new("StringValue", workspace["somePlace"]) strV.Value = match; strV.Name = "String Match!" end
Useful Link: http://wiki.roblox.com/index.php?title=String_pattern