Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local s = "Hey\nAP There And YeaAP hAi\n"
- --[[
- gibberish test string, I was inserting the first things I could think of. the capital A in the final "hi" was inserted long ago when I was testing to make sure substrings could work when their component letters still existed after them. They couldn't.
- ]]--
- local insane_test_string = "abcTESTdeabcbaTESTbweufTESTnajnaiaa;lfoail;T;;;;;TEST;;;;;;;TEEST;;;;;;;"
- function string.rfind(str, substr, plain) --plain is included for you to pass to find if you wish to ignore patterns
- assert(substr ~= "") --An empty substring would cause an endless loop. Bad!
- local plain = plain or false --default plain to false if not included
- local index = 0
- --[[
- Watch closely... we continually shift the starting point after each found index until nothing is left.
- At that point, we find the difference between the original string's length and the new string's length, to see how many characters we cut out.
- ]]--
- while true do
- local new_start, _ = string.find(str, substr, index, plain) --index will continually push up the string to after whenever the last index was.
- if new_start == nil then --no match is found
- if index == 0 then return nil end --if no match is found and the index was never changed, return nil (there was no match)
- return #str - #str:sub(index) --if no match is found and we have some index, do math.
- end
- --print("new start", new_start)
- index = new_start + 1 --ok, there was some kind of match. set our index to whatever that was, and add 1 so that we don't get stuck in a loop of rematching the start of our substring.
- end
- end
- print("Length of test string is", #s)
- print("Test: Multiple instances, single char '\\n'", string.rfind(s, "\n"))
- assert(string.rfind(s, "\n") == #s)
- print("Passed first assertion")
- print("Test: 1 instance, single char '\\n'", string.rfind(s:sub(1, 5), "\n"))
- assert(string.rfind(s:sub(1, 5), "\n") == 4)
- print("Passed second assertion")
- print("Test: Multiple instances, substring 'AP'", string.rfind(s, "AP"))
- assert(string.rfind(s, "AP") == 21)
- print("Passed third assertion")
- print(string.rfind(insane_test_string, "TEST"))
- assert(string.rfind(insane_test_string, "TEST") == 50)
- print("Passed fourth assertion")
- print(string.rfind("a", "a"))
- assert(string.rfind("a", "a") == 1)
- print("Passed fifth assertion")
- print("Test: Substring not present", string.rfind("xyz", "0"))
- assert(string.rfind("xyz", "0") == nil)
- print("Passed sixth assertion")
- print("Passed all assertions")
- print("Final test: Empty substring", pcall(function() string.rfind("xyz", "") end)) --this should fail!
- --[[
- if you're interested in speed...
- test A
- test string = long lorem ipseum repeated 10k times
- substring = e
- time lua rfind_speed.lua
- 27 910 000 --len of string
- 27 909 997 --the actual result
- real 0m0.995s
- user 0m0.869s
- sys 0m0.027s
- time luajit rfind_speed.lua
- 27 910 000
- 27 909 997
- real 0m0.212s
- user 0m0.140s
- sys 0m0.027s
- ~~~~~~~~~~~~~~~~~~~~~~
- test B
- same test string
- substring = diam, which appears 3 times in each of the 10k repetitions
- time lua rfind_speed.lua
- 27 910 000
- 27 909 831
- real 0m0.243s
- user 0m0.135s
- sys 0m0.062s
- time luajit rfind_speed.lua
- 27 910 000
- 27 909 831
- real 0m0.146s
- user 0m0.070s
- sys 0m0.025s
- my ubuntu vm has about 2 gb mem and my processor is i3-6100. it isnt configured for a good passthrough or anything like that.
- i dont know how to feel about this. not sure what the standards are but it seems like it will work fine enough unless you're scanning 27million chars 10 times in a loop.
- ]]--
- --I have not considered drugs before, but after trying to make this function perfect...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement