Filtering with Whitespace (\n)

Currently, I am attempting to make players add whitespace (\n) on their text. This would allow them to add bullets or make a list. However, the problem with this is the filtering.

The result of the TextService returns a 1 line string, instead of the whitespace still included. So it’s like this:

local String = "aaaa\nbbbbb"
-- aaaaaaa
-- bbbbbb
Filter Result: 
"aaaabbbb"

Since this will make it one line, I am attempting to split the string with the separator as the whitespace (\n). This would allow me to filter every part of the string separated by the whitespace. However, I am not getting the results I want.

Attempts:

  1. I tried using HttpService:JSONEncode to not format it, then use \n on the second argument of string.split, but it doesn’t work.
  2. Also, %s seems to not be working on the 2nd argument of string.split when encoded and not encoded…

Any suggestion or solution?

local FilterWhitespace = string.split(String, "\\n")
print(FilterWhitespace)

After inputting a text in TextBox with a whitespace, it still prints 1 as the length of the table.

@TheCarbyneUniverse

So apparently, multiline textboxes don’t need \\n, \n works just fine. But if you have deliberately put \n like the above example, then the double slashes are necessary. It should work with string.split(str, '\n') only when it’s a text box.

Thanks for the info. However, I have another question. Is it possible to know all the location the split happened? (If it got split in string position 4, then it will say 4.)

I’m getting the correct TextFilterResult text when I try it

local str = "aaaa\nbbbb"

print(game:GetService'TextService':FilterStringAsync(str, 112896842, 1):GetNonChatStringForBroadcastAsync())

image

image

Ok, so I came up with a solution that works for most (if not all) cases and requires only 1 call to FilterStringAsync:

local TextService = game:GetService'TextService'
local function Filter(Text, UserId)
	UserId = tonumber(UserId) or 112896842
	
	local Original = Text
	local Newlines = {}
	
	local function Insert(Text, Index, Insert)
		return string.sub(Text, 1, Index - 1) .. Insert .. string.sub(Text, Index)
	end
	
	local function Remove(Text, Index)
		return string.sub(Text, 1, Index - 1) .. string.sub(Text, Index + 1)
	end
	
	local i = 1
	while true do
		local Index = string.find(Text, "\n", i)
		if Index then
			table.insert(Newlines, Index)
			i = Index + 1
		else
			break
		end
	end
	
	local Filtered = TextService:FilterStringAsync(Original, UserId, 1):GetNonChatStringForBroadcastAsync()
	local _, Matches = string.gsub(Filtered, " ", "")
	Filtered = string.gsub(Filtered, "\n", " ")
	for i, Index in pairs(Newlines) do
		local Character = string.sub(Filtered, Index, Index)
		if Character == " " or (Matches <= 0 and Character == "#") then
			Filtered = Remove(Filtered, Index)
			Filtered = Insert(Filtered, Index, "\n")
		else
			Filtered = Insert(Filtered, Index, "\n")
		end
	end
	return Filtered
end

warn(Filter("hello world"))
warn(Filter("hello\nworld"))
warn(Filter("123456789"))
warn(Filter("123456789\n11111111"))
warn(Filter("aaaa\nbbbb"))
warn(Filter("aaa\nbbb\nccc\nddd\neee"))
warn(Filter("\n1. aaa\n2. bbb\n3. ccc"))
warn(Filter("\n\n\n1. aaa\n\n\n2. bbb\n\n\n3. ccc\n\n\n"))
warn(Filter("\n1. test\n\n\n2. test\n\n\n3. test"))
warn(Filter("############"))
warn(Filter("##\n########\n\n##"))

The reason is because multiline textboxes are actually called ‘string literals’ and they take the literal form of the string, rather than parsing escape sequences and so forth. You can also nest them with equals signs.

local searchFor = [==[ var=[[test]] ]==]
local yep = [======[ this bad boy can fit so much string literals in it ]======]

1 Like