How to check difference of two strings

  1. What do you want to achieve? Keep it simple and clear!

I want to check and display the difference between two strings

  1. What is the issue? Include screenshots / videos if possible!

Right now I can only see if they are different in a boolean, I want to show what changes from a string to the other

I want to display something like this
immagine
in RichText,

If you’re looking into comparing strings, this may help you

2 Likes

I think I found something similiar to what I’m looking for using LCS:

I’m kinda making a terminal in lua that can also load many of these lua command line utilities

This just looks like they’re storing the old string and displaying it with the new string.

I just decided to write a system for this, it works well.

local gui = script.Parent
local frame = gui:WaitForChild("Frame")
local old = frame:WaitForChild("Old")
local new = frame:WaitForChild("New")

local function compareStrings(oldString, newString)
	local iterator = 0
	local comparedOldString = ""
	local comparedNewString = ""
	
	if oldString:len() > newString:len() then
		for character in oldString:gmatch(".") do
			iterator += 1
			if character:match("%s") then
				comparedOldString..=character
				comparedNewString..=character
				continue
			end
			if iterator <= newString:len() then
				local currentNewCharacter = newString:sub(iterator, iterator)
				if character == currentNewCharacter then
					comparedOldString..="<font color=\"#000000\">"..character.."</font>"
					comparedNewString..="<font color=\"#000000\">"..currentNewCharacter.."</font>"
				else
					comparedOldString..="<font color=\"#aa0000\">"..character.."</font>"
					comparedNewString..="<font color=\"#00aa00\">"..currentNewCharacter.."</font>"
				end
			else
				comparedOldString..="<font color=\"#aa0000\">".."<s>"..character.."</s>".."</font>"
			end
		end
		
	elseif oldString:len() <= newString:len() then
		for character in newString:gmatch(".") do
			iterator += 1
			if character:match("%s") then
				comparedOldString..=character
				comparedNewString..=character
				continue
			end
			if iterator <= oldString:len() then
				local currentOldCharacter = oldString:sub(iterator, iterator)
				if character == currentOldCharacter then
					comparedOldString..="<font color=\"#000000\">"..currentOldCharacter.."</font>"
					comparedNewString..="<font color=\"#000000\">"..character.."</font>"
				else
					comparedOldString..="<font color=\"#aa0000\">"..currentOldCharacter.."</font>"
					comparedNewString..="<font color=\"#00aa00\">"..character.."</font>"
				end
			else
				comparedNewString..="<font color=\"#00aa00\">"..character.."</font>"
			end
		end
	end
	
	old.Text = comparedOldString
	new.Text = comparedNewString
end

local oldString = ""
local newString = ""
compareStrings(oldString, newString)

If old text is removed from the new text (“Hello 123” to “Hello”):
image

If old text is replaced in the new text (“Hello 123” to “Hello 456”):
image

If new text is added to the old text (“Hello” to “Hello 123”):
image

Organisation:

image

Model file:
repro.rbxm (5.1 KB)

1 Like
local gui = script.Parent
local frame = gui:WaitForChild("Frame")
local old = frame:WaitForChild("Old")
local new = frame:WaitForChild("New")

local function compareStrings(oldString, newString)
	local iterator = 0
	local comparedOldString = ""
	local comparedNewString = ""

	local strings = if oldString:len() > newString:len() then {oldString, newString} else {newString, oldString}
	for character in strings[1]:gmatch(".") do
		iterator += 1
		if character:match("%s") then
			comparedOldString..=character
			comparedNewString..=character
		else
			if iterator <= strings[2]:len() then
				local otherCharacter = strings[2]:sub(iterator, iterator)
				if character == otherCharacter then
					comparedOldString..="<font color=\"#000000\">"..character.."</font>"
					comparedNewString..="<font color=\"#000000\">"..otherCharacter.."</font>"
				else
					comparedOldString..="<font color=\"#aa0000\">"..character.."</font>"
					comparedNewString..="<font color=\"#00aa00\">"..otherCharacter.."</font>"
				end
			else
				if table.find(strings, newString) == 2 then
					comparedOldString..="<font color=\"#aa0000\">".."<s>"..character.."</s>".."</font>"
				elseif table.find(strings, oldString) == 2 then
					comparedNewString..="<font color=\"#00aa00\">"..character.."</font>"
				end
			end
		end
	end

	old.Text = comparedOldString
	new.Text = comparedNewString
end

local oldString = ""
local newString = ""
compareStrings(oldString, newString)

Decided to come back and make the code much more concise/readable.

1 Like

Thank you! Can your system provide the output in one single string with reds and greens?

Yes but then you won’t get the full context, if a character is replaced with another then the replacement can only be shown in one color (you can’t display the old character in red and the new character in green in the same string).

local gui = script.Parent
local frame = gui:WaitForChild("Frame")
local compared = frame:WaitForChild("Compared")

local function compareStrings(oldString, newString)
	local iterator = 0
	local comparedString = ""

	local strings = if oldString:len() > newString:len() then {oldString, newString} else {newString, oldString}
	for character in strings[1]:gmatch(".") do
		iterator += 1
		if character:match("%s") then
			comparedString..=character
		else
			if iterator <= strings[2]:len() then
				local otherCharacter = strings[2]:sub(iterator, iterator)
				if character == otherCharacter then
					comparedString..="<font color=\"#000000\">"..character.."</font>"
				else
					comparedString..="<font color=\"#00aa00\">"..character.."</font>"
				end
			else
				if table.find(strings, newString) == 2 then
					comparedString..="<font color=\"#aa0000\">".."<s>"..character.."</s>".."</font>"
				elseif table.find(strings, oldString) == 2 then
					comparedString..="<font color=\"#00aa00\">"..character.."</font>"
				end
			end
		end
	end

	compared.Text = comparedString
end

local oldString = ""
local newString = ""
compareStrings(oldString, newString)

repro.rbxm (4.9 KB)

Here is that version though.

1 Like