"string.gsub" multiple times

I’m trying to create a (low effort) syntax highlighting textbox.
My script can detect the keywords in the textbox, but can’t highlight all of them.
This is the main part of the script:

local to_highlight = {“script”, “game”}

for i, v in ipairs(to_highlight) do --don’t mind the extra back-slashes, they’re not in my actual code
syntax_overlay.Text = string.gsub(textbox.Text, v, “</font color=‘rgb(255, 255, 0)’>”…v…"<//font>)
end

What I see when I type into the box:

Now, let’s pretend bold words are the syntax highlighted words.

1 | ijkdkj script sdfjjkfghjksdfgsdfg
2 | flk,mfdfd,mfdlk game
3 | script

Only one word is highlighted.
I’ve searched for a fix, but I’ve not found one.

EDIT: I forgot to specify that this is inside of a “.changed” function.

1 Like

Try

local to_highlight = {"script", "game"}

for i, v in ipairs(to_highlight) do --don’t mind the extra back-slashes, they’re not in my actual code
 textbox.Text = string.gsub(textbox.Text, v, "</font color='rgb(255, 255, 0)'>"…v…"<//font>")
end

Why have syntax_overlay? Delete it and try this with RichText

2 Likes

The second step in your loop is overwriting the first step. Consider maybe doing

local textStart  = textbox.Text
for i, v in ipairs(to_highlight) do 
  textStart =  textStart:gsub(v, [[<font color='rgb(255, 255, 0)'>]]…v…[[</font>]])
end
syntax_overlay.Text = textStart 

1 Like

Had to keep the syntax overlay as my Roblox Studio crashes because it creates an infinite loop (I’m doing this inside of a “.changed” function). Neither work. I should’ve specified that this is inside of a “.changed” function.

Do you have RichText enabled? Is anything interfering with the .Changed() event? Try printing to the output (maybe the gsubbed text) every time it highlights the new text.

1 Like

Yes, I have rich text enabled. I don’t think anything is interfering with the .Changed event. I’ll try printing the output tomorrow as I’m quite sleepy.

I’ll send a pic of what I was getting before testing the other things tomorrow. (If I’m able to undo that much)

My original version that only highlights one word at a time:

Okay so the issue I think is you might be overwriting the previous gsub when you’re only making one change at a time, so only the last keyword’s highlighting is being applied. This may fix it (or may not, since I haven’t tested it.)

local to_highlight = {"script", "game"}

local highlighted_text = textbox.Text

for i, v in ipairs(to_highlight) do
    highlighted_text = string.gsub(highlighted_text, v, "<font color='rgb(255, 255, 0)'>" .. v .. "</font>")
end

syntax_overlay.Text = highlighted_text

Let me know if that helps, or if you encounter any further issues!

Edit: just noticed someone else in this thread suggested this fix. When I tested my version though, it seemed to work seamlessly, so I’d recommend giving it another go.

1 Like
local textbox = script.Parent
local to_highlight = {"script", "game"}

textbox.Text = "ijkdkj script sdfjjkfghjksdfgsdfg\nflk,mfdfd,mfdlk game\nscript"

for _, keyword in ipairs(to_highlight) do
    local highlight = string.format('<font color="rgb(255, 255, 0)">%s</font>', keyword)
    textbox.Text = textbox.Text:gsub(keyword, highlight)
end

Just a (low effort) guess.
(not going to wright out a picture to test with when you could have simply posted the text)

1 Like

By gsubbing the string you’re essentially just creating a recursive loop on the same text over and over again so it will keep detecting the same highlighted word. Below is a snippet that will work with what you’ve asked for!

local to_highlight = {"script", "game"}
local myTextBox	= script.Parent.TextBox

myTextBox:GetPropertyChangedSignal("Text"):Connect(function()
	local toSyntax	= myTextBox.Text:split(".")
	local newPhrase	= ""
	
	for i,v in toSyntax do
		local toAdd	= v
		
		if table.find(to_highlight, v) then
			toAdd	= [[<font color="rgb(255,255,0)">]]..v.."</font>"
		end
		
		if i < #toSyntax then
			toAdd	= toAdd.."."
		end
		
		newPhrase	= newPhrase..toAdd
	end
	
	myTextBox.Text	= newPhrase
end)
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.