1

HTML テキストをサネタイズする関数を作成しようとしています。問題定義:

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

これは次の場合に機能します。

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

ただし、HTML の仕様では、スペースが 2 つ以上ある場合のみ、余分なスペースを に置き換える必要があります 。したがって、単一のスペースを置き換える必要はありません。複数ある場合、1 つのスペースは変換されませんが、残りは に変換され ます。言い換えれば、次の機能が必要です。

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

f() の書き方について何か考えはありますか?

4

3 に答える 3

2

(アレックスの回答に関するメモ。フォーマットされたコードを含めることができるように、ここに投稿しました。)

最初の 4 つの gsub 呼び出しは、ルックアップ テーブルを 2 番目の引数として取る 1 つの呼び出しに置き換えることができます。これは、コードを 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
于 2011-08-29T21:27:00.620 に答える
2

あなたは次のようなことを試すかもしれません

txt:gsub("( +)", function(c) return " "..("&nbsp;"):rep(#c-1) end)
于 2011-08-29T08:15:28.093 に答える
0

関数を使用する 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; '
于 2011-08-29T08:28:49.260 に答える