local function remove(str, start, _end) local start_part = str:sub(1, start - 1) local end_part = str:sub(_end + 1, -1) return start_part .. end_part end local function remove_patterns(str, pattern) while true do local rem_start, rem_end, _ = str:find(pattern) if rem_start == nil then break end str = remove(str, rem_start, rem_end) end return str end local function ispali(str) str = str:lower() -- format str = remove_patterns(str, "%s") str = remove_patterns(str, "%p") return str == str:reverse() end local function test(str) print(("%s: %q"):format(str, ispali(str))) end test("step on no pets") test("banana") print() test("Step. On no pets!") test("Banana??")