challenge 改行をBRタグに置き換える

一部のHTMLタグを通すフィルタ どう書く?の続編です。 前回の条件を満たしつつ、入力中の改行を<br/>に置き換えてください。ただし、たとえば"<a\nhref=...>"といったようにタグの中に改行がある場合、単純に置換するわけには行かないことに注意してください。

また、ユーザの入力注の<br>は<br/>に変換してください。

このお題はperezvonさんの提案を元にした三部作の二問目です。ご協力ありがとうございました。

Posted feedbacks - C#

前回(#2937)のescapeメソッドに改行の置換を追加しました。
 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Text;
using System.Text.RegularExpressions;

class HtmlFilter {
    private Regex _regFilter;
       
    public HtmlFilter() {
        _regFilter = new Regex(@"(<(?<begin>\w+)(?:\s+(?<attr>\w+\s*=\s*"
             + "(?:'[^']*'|\"[^\"]*\")" + @"\s*)*)?/?>)|(</(?<end>\w+)\s*>)",
            RegexOptions.IgnoreCase | RegexOptions.Compiled);
    }
    
    public string escape(string s) {
        return s.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;")
            .Replace(System.Environment.NewLine, "<br/>");
    }
    
    public string filter(string input) {
        bool tagA = false;
        int index = 0, tagStrong = 0;
        StringBuilder sb = new StringBuilder(input.Length * 2);

        for (Match m = _regFilter.Match(input); m.Success; m = _regFilter.Match(input, index)) {
            sb.Append(escape(input.Substring(index, m.Index - index)));
            index = m.Index + m.Length;

            if (m.Groups["begin"].Success) {
                switch (m.Groups["begin"].Value.ToLower()) {
                    case "a":
                        string href = "";
                        foreach (Capture capture in m.Groups["attr"].Captures) {
                            string[] attribute = capture.Value.Split('=');
                            if (attribute[0].Trim().Equals("href", StringComparison.OrdinalIgnoreCase)) {
                                href = " href=" + attribute[1].Trim();
                                break;
                            }
                        }
                        sb.Append(tagA ? "</a><a" : "<a").Append(href).Append(">");
                        tagA = true;
                        break;
                    case "strong":
                        tagStrong++;
                        sb.Append("<strong>");
                        break;
                    case "br":
                        sb.Append("<br/>");
                        break;
                    default:
                        sb.Append(escape(m.Value));
                        break;
                }
            } else {
                switch (m.Groups["end"].Value.ToLower()) {
                    case "a":
                        if (tagA) {
                            sb.Append("</a>");
                            tagA = false;
                        } else {
                            sb.Append(escape(m.Value));
                        }
                        break;
                    case "strong":
                        if (tagStrong > 0) {
                            tagStrong--;
                            sb.Append("</strong>");
                        } else {
                            sb.Append(escape(m.Value));
                        }
                        break;
                    default:
                        sb.Append(escape(m.Value));
                        break;
                }
            }
        }

        sb.Append(escape(input.Substring(index, input.Length - index)));

        while (tagStrong-- > 0) sb.Append("</strong>");
        if (tagA) sb.Append("</a>");

        return sb.ToString();
    }
}
class Program {
    static void Main(string[] args) {
        HtmlFilter f = new HtmlFilter();
        string text = System.IO.File.ReadAllText("hoge.txt");
        Console.WriteLine(f.filter(text));
    }
}

Index

Feed

Other

Link

Pathtraq

loading...