Need help with string.sub()

Hello, i am Eterna. I need help with spliting a Region3int16 into two Vectors. I become the idea to converting the Region3 in a string, then spliting it into singular number only in string form and reconverting it into a number and with others number to form a Vector3. My problem is: My terrain Max extends is: -32000, -32000, -32000, 32000, 32000, 32000. Then i use this: string.sub(MaxExtends, 0, 6) and i got a part from the Region3int16! But if it was other, irregular, like this: -1, -60, -503, 600, 5000, 435627, then how can i make a method to always get only one number of the Region3int16?

Great idea for a way of doing this - I can see that there is always 5 commas in each string(Region3), so we can count those and move along each character individually:

local Region3 = Region3int16.new(Vector3int16.new(12, 34, 56), Vector3int16.new(78, 910, 1112));
local string_Region3 = tostring(Region3);
local nums = {};
local vectors = {};
local comma_count = 0;
local comma_threshold = 3; --how many commas before starting next vector

local function convert(nums_position)
  nums_position = tonumber(nums_position);
end

--===============go through and read each character and get nums
nums[1] = "";
for i = 1, string.len(string_Region3) do
  local char = string.sub(string_Region3, i, i)
  print('char:', char)

  if char == ',' or char == ';' then
    convert(#nums)
    nums[#nums+1] = "";
    i = i + 1 --skip over the space after a comma 
  else
    nums[#nums] = nums[#nums] .. char 
  end
end
convert(#nums)

--===========create the vectors from the array of nums
for k = 1, #nums do print('num', k, nums[k]) end

local vector_length = 3;
local vector_pos = math.ceil(#nums/vector_length) 
for j = 1, vector_pos do
  local base_position = 1 + vector_length*(j-1);
  vectors[vector_pos] = Vector3.new(nums[base_position], nums[base_position+1], nums[base_position+2]); -- or Vector3int16.new();
  print('Vector', vector_pos, 'is', vectors[vector_pos])
end

Whew that was a good challenge. Watch the output to see how it does it

2 Likes

Why not just use pattern matching and tonumber?

http://lua-users.org/wiki/PatternsTutorial

^(%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+)$ maybe (haven’t used patterns in a while)

2 Likes
tonumber(string:split(β€œ, ”)[1])

The 1 is which number you want to get. 1 could be any number to how ever many numbers there are(length of the array). String:Split() just splits a string with the given separator and returns an array.

2 Likes

If anyone uses this, remember to use " instead of le Smart Quotes β€œ and ”

2 Likes

I understand your question a little better. Using the code that I responded with, you can return 2 vectors.

local function Region3ToVector3(region3)
local numbers = tostring(region3):split(β€œ, β€œ)
return Vector3.new(tonumber(numbers[1]), tonumber(numbers[2]), tonumber(numbers[3])), Vector3.new(tonumber(numbers[4]), tonumber(numbers[5]), tonumber(numbers[6]))
end
3 Likes

Wow, @JoelBrd , it realy worked, thanks a lot! @anon66957764, sorry ,but i dont use pattern matching and dont have the time to learn it. @Alphexus, sorry but i dont very good know the strings methods, this is why i asked here, but thanks for trying! Edit: Hm, i find Integern and Alphexus scripts very good, but integern script is longer, but i can more see the technical functionement of it, but Alphexus skript is shorter. Sorry Integern, but i chose Alphexus because it was shorter as your, but your skript is still great

@Alphexus has provided the best method for your case.

1 Like
local function corners(region3int16)
    local x1, y1, z1, x2, y2, z2 = tostring(region3int16):match('^(%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+), (%-?%d+)$')

    return Vector3.new(tonumber(x1), tonumber(y1), tonumber(z1)), Vector3.new(tonumber(x2), tonumber(y2), tonumber(z2))
end

Untested.

1 Like

Thanks, but can you say me what the script do?

it’s a function. you call it with Region3int16 and it gives you 2 vectors

1 Like

@Alphexus, just want to say you that i have need to change a bit your script snippet. Here is what it now look:

local function RegionToVector3()
local numbers = tostring(region3):split(", ")
local numbers1 = numbers[3]:split(";")
return Vector3.new(tonumber(numbers[1]), tonumber(numbers[2]), tonumber(numbers1[1])), Vector3.new(tonumber(numbers[4]), tonumber(numbers[5]), tonumber(numbers1[2]))
end 

Why i made this? The reason was that a Region3int16 is printed as:
Num1, Num2, Num3; Num4, Num5, Num6 --Between the Num3 and Num4 is a β€œ;”, then i have need to re-split the string to have a full Vector3. Just want to say this, but thank a lot, it worked!