Advertisement
AllisterBrooks

Lua rfind

Sep 25th, 2020 (edited)
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.67 KB | None | 0 0
  1. local s = "Hey\nAP There And YeaAP hAi\n"
  2. --[[
  3. 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.
  4. ]]--
  5. local insane_test_string = "abcTESTdeabcbaTESTbweufTESTnajnaiaa;lfoail;T;;;;;TEST;;;;;;;TEEST;;;;;;;"
  6.  
  7. function string.rfind(str, substr, plain) --plain is included for you to pass to find if you wish to ignore patterns
  8.     assert(substr ~= "") --An empty substring would cause an endless loop. Bad!
  9.   local plain = plain or false --default plain to false if not included
  10.   local index = 0
  11.   --[[
  12.     Watch closely... we continually shift the starting point after each found index until nothing is left.
  13.         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.
  14.   ]]--
  15.   while true do
  16.     local new_start, _ = string.find(str, substr, index, plain) --index will continually push up the string to after whenever the last index was.
  17.     if new_start == nil then --no match is found
  18.             if index == 0 then return nil end   --if no match is found and the index was never changed, return nil (there was no match)
  19.       return #str - #str:sub(index)  --if no match is found and we have some index, do math.
  20.     end
  21.     --print("new start", new_start)
  22.     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.
  23.   end
  24. end
  25.  
  26. print("Length of test string is", #s)
  27.  
  28. print("Test: Multiple instances, single char '\\n'", string.rfind(s, "\n"))
  29. assert(string.rfind(s, "\n") == #s)
  30. print("Passed first assertion")
  31.  
  32. print("Test: 1 instance, single char '\\n'",         string.rfind(s:sub(1, 5), "\n"))
  33. assert(string.rfind(s:sub(1, 5), "\n")  == 4)
  34. print("Passed second assertion")
  35.  
  36. print("Test: Multiple instances, substring 'AP'",   string.rfind(s, "AP"))
  37. assert(string.rfind(s, "AP") == 21)
  38. print("Passed third assertion")
  39.  
  40. print(string.rfind(insane_test_string, "TEST"))
  41. assert(string.rfind(insane_test_string, "TEST") == 50)
  42. print("Passed fourth assertion")
  43.  
  44. print(string.rfind("a", "a"))
  45. assert(string.rfind("a", "a") == 1)
  46. print("Passed fifth assertion")
  47.  
  48. print("Test: Substring not present", string.rfind("xyz", "0"))
  49. assert(string.rfind("xyz", "0") == nil)
  50. print("Passed sixth assertion")
  51.  
  52. print("Passed all assertions")
  53.  
  54. print("Final test: Empty substring", pcall(function() string.rfind("xyz", "") end)) --this should fail!
  55.  
  56. --[[
  57. if you're interested in speed...
  58. test A
  59. test string = long lorem ipseum repeated 10k times
  60. substring = e
  61. time lua rfind_speed.lua
  62. 27 910 000 --len of string
  63. 27 909 997 --the actual result
  64.  
  65. real    0m0.995s
  66. user    0m0.869s
  67. sys 0m0.027s
  68.  
  69. time luajit rfind_speed.lua
  70. 27 910 000
  71. 27 909 997
  72.  
  73. real    0m0.212s
  74. user    0m0.140s
  75. sys 0m0.027s
  76. ~~~~~~~~~~~~~~~~~~~~~~
  77. test B
  78. same test string
  79. substring = diam, which appears 3 times in each of the 10k repetitions
  80. time lua rfind_speed.lua
  81. 27 910 000
  82. 27 909 831
  83.  
  84. real    0m0.243s
  85. user    0m0.135s
  86. sys 0m0.062s
  87.  
  88. time luajit rfind_speed.lua
  89. 27 910 000
  90. 27 909 831
  91.  
  92. real    0m0.146s
  93. user    0m0.070s
  94. sys 0m0.025s
  95.  
  96. 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.
  97. 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.
  98. ]]--
  99.  
  100. --I have not considered drugs before, but after trying to make this function perfect...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement