一部のHTMLタグを通すフィルタ
Posted feedbacks - Scheme
Gauche で書いてみました。まず、 HTML を HtmlPrag を使って SXML 形式に変換し、その上で属性のフィルタリングをします。タグの < や > を <、 > に変換するのは正規表現を使っています。ひとつのタグが複数行に分けて書かれている場合には対応していません。
see: HtmlPrag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | (load "htmlprag")
(use util.list)
(use sxml.serializer)
(use sxml.sxpath)
(use sxml.tools)
(use sxml.tree-trans)
(define (filter-html shtml)
(pre-post-order shtml
`((*default* . ,(lambda c c))
(*text* . ,(lambda (_ c) c))
(br . ,(lambda br
(sxml:change-attrlist! br '())
br))
(strong . ,(lambda strong
(sxml:change-attrlist! strong '())
strong))
(a . ,(lambda a
(sxml:change-attrlist! a
(cond-list
(((if-car-sxpath "./@href") a) => values)
(((if-car-sxpath "./@name") a) => values)))
a)))))
(define (main args)
(display
(call-with-input-file (cadr args)
(lambda (iport)
(regexp-replace-all
#/<((?!\/?a\b|\/?br\b|\/?strong\b|!--)[^>]*(?!--))>/
(srl:sxml->xml (filter-html (html->sxml iport)))
"<\\1>")))))
|


にしお
#3410()
Rating0/0=0.00
このお題はperezvonさんの提案を元にしています。ありがとうございました。 ただ、いきなりだと難しいかと思ったので、肝の部分以外を先に出題しました。このお題は続編で徐々に難しくなっていきます。
追記:属性に<や>が含まれてしまうケースに漏れのある解答が多いようなのでテストケースを追加します。 これは「この出力なら十分」という意味です。この出力の通りでなければいけないという意味ではありません。 <script foo="<script>alert('bar')</script>">alert('foo')</script> <script foo="<script>alert('bar')</script>">alert('foo')</script> <script foo="<a href='link'>link</a>">alert('foo')</script> <script foo="<a href='link'>link</a>">alert('foo')</script> <a href='www.g>oogle.com'>link</a> <a href="./www.g%3Eoogle.com">link</a>[ reply ]