Любая умная идея для этой проблемы gsub ()?(Санация HTML с помощью Lua) - PullRequest
1 голос
/ 29 августа 2011

Я пытаюсь написать функцию, которая обрабатывает текст HTML. Определение проблемы:

function f(txt) return txt:gsub("%s"," ")

Теперь это работает для следующего:

f(" hello  buddy!") ---> " hello  buddy!"

Но в соответствии со спецификацией HTML, только когда есть два или более пробелов, дополнительные должны быть заменены на  . Таким образом, один пробел не нужно заменять. Если их больше, один пробел не будет преобразован, а остальные будут преобразованы в  . Другими словами, мне нужна функция, которая:

f(" hello  buddy!") ---> " hello  buddy!"
f("   ") ---> "  &nbsp"
f(" ") ---> " "
f("hello buddy!") ---> "hello buddy!"

Есть идеи, как я могу написать f ()?

Ответы [ 3 ]

2 голосов
/ 30 августа 2011

(Примечания относительно ответа Алекса. Опубликовано здесь, чтобы я мог включить отформатированный код.)

Первые 4 вызова gsub можно заменить одним вызовом, для которого в качестве второго аргумента используется таблица поиска.Это намного быстрее, чем 4 прохода по коду.

function sanitize(txt)
    local replacements = {
        ['&' ] = '&', 
        ['<' ] = '&lt;', 
        ['>' ] = '&gt;', 
        ['\n'] = '<br/>'
    }
    return txt
        :gsub('[&<>\n]', replacements)
        :gsub(' +', function(s) return ' '..('&nbsp;'):rep(#s-1) end)
end
2 голосов
/ 29 августа 2011

вы можете попробовать что-то вроде

txt:gsub("( +)", function(c) return " "..("&nbsp;"):rep(#c-1) end)
0 голосов
/ 29 августа 2011

Благодаря подсказке jpjacobs с использованием функции, вот полный код функции и пример:

---This function sanetizes a HTML string so that the following characters will be shown
-- correctly when the output is rendered in a browser:
-- & will be replaced by &amp;
-- < will be replaced by &lt;
-- > will be replaced by &gt;
-- \n will be replaced by <br/>;
-- (more than one space) will be replaced by &nbsp; (as many as required)
-- @param txt the input text which may have HTML formatting characters
-- @return the sanetized HTML code
function sanitize(txt)
    txt=txt:gsub("%&","&amp;")
    txt=txt:gsub("%<","&lt;")
    txt=txt:gsub("%>","&gt;")
    txt=txt:gsub("\n","<br/>")
    txt=txt:gsub("(% +)", function(c) return " "..("&nbsp;"):rep(#c-1) end)
    return txt
end

text=[[    <html>   hello  &bye </html> ]]

print("Text='"..text.."'")
print("sanetize='"..sanitize(text).."'")

Вывод:

Text='    <html>   hello  &bye </html> '
sanetize=' &nbsp;&nbsp;&nbsp;&lt;html&gt; &nbsp;&nbsp;hello &nbsp;&amp;bye &lt;/html&gt; '
...