Suppose I have a string (PlayerCodeString) that a player defines, but I know what the string is in this case: “Hey, the code is 123. I repeat: the code is 123.”
The code can be anything as the player defines, but I know it’s a number, so I know I can use string.match(PlayerCodeString, "%d+") to get the code. I can also use string.gmatch(PlayerCodeString, "%d+") to verify that the code the player defines is the same.
But I want to get the position of the matches. I know I can use string.find(PlayerCodeString, "%d+") to find the position of the first occurrence, but I don’t think I can find the second one by simply using this function.
Is there a way to find the positions of the matches?
local str = ""
local pat = ""
local len_offset = 0
local occurs = {}
repeat
local s, e = string.find(str, pat)
if e then
table.insert(occurs, #occurs + 1, {s+len_offset, e+len_offset})
str = string.sub(str, e+1)
len_offset = len_offset + e
end
until (not s)
I would imagine there is a better way but I am not really friends with strings
if you want to get the position of a certain character in a string then there’s more than one method, way more than 1.
Using string.find()
this is probably the canonical way to do get the position of an element :
str = "I repeat the code is 123"
local position = string.find(str,"r")
print(position) --> 3 , as whitespaces count as characters
A function for it,
function getPosition(str,char)
assert(str:find(char),"\r\r"..char.." not found in string \r\r")
local find = string.find(str,char)
return find
end
My own invented function, made this a long time ago (ignore parameter init)
(also uncertain about it's efficiency)
function nmatch(s,pattern,init)
if type(s) == "string" then
else
return nil
end
if init then
local sub = s:sub(init)
if sub:match(pattern)
then for i = 1,#sub do
if sub:sub(i,i) == pattern then
else
i = nil
return i
end
end
return
end
end
if not init then
if s:match(pattern) then
for i = 1,#s do
if s:sub(i,i) == pattern then
return i
end
end
else
return nil
end
end
end
print(nmatch("strring","r")) ---> first occurence is at 3, so 3 prints
Although the solution is correct. I tried to use it on my “HighlightTheSameText” Script and then it almost crashed my game when I highlighted the text that will detect if there is more and then find it’s position.
At least the script timed out for throwing 50,000 events very fast.
Script.
wait(1)
local textBox = script.Parent.Parent
local function showSelection()
local Found = 0
if textBox.CursorPosition == -1 or textBox.SelectionStart == -1 then return end
local selectedText = string.lower(string.sub(
textBox.Text,
math.min(textBox.CursorPosition, textBox.SelectionStart),
math.max(textBox.CursorPosition, textBox.SelectionStart)
))
local TextboxText = string.lower(textBox.Text)
if selectedText == "" then return end
local matches = {}
local matchesPosition = {}
for m in string.gmatch(textBox.Text, selectedText) do
local str = textBox.Text
local len_offset = 0
local occurs = {}
repeat
local s, e = string.find(str, selectedText)
if e then
table.insert(occurs, #occurs + 1, {s+len_offset, e+len_offset})
str = string.sub(str, e+1)
len_offset = len_offset + e
end
until (not s)
-- table.insert(matchesPosition, str)
table.insert(matches, m)
end
for i,v in pairs(matches) do
Found = Found + 1
end
if Found >= 1 then
-- Event will happen here.
end
end
textBox:GetPropertyChangedSignal("CursorPosition"):Connect(showSelection)
textBox:GetPropertyChangedSignal("SelectionStart"):Connect(showSelection)
Is there any way I can fix this bug so my game does not crash and timeout?