代码之家  ›  专栏  ›  技术社区  ›  epitka

正则表达式挑战

  •  1
  • epitka  · 技术社区  · 15 年前

    是否可以放置一个regex表达式,该表达式将:

    1. 查找以“%”开头、以“%”结尾的块
    2. 在该块中,将所有XML特殊字符替换为:
      "apos;lt;>&
    3. 将所有内容保持在<%=%>或<%%>之间,除非确保<%或<%=之后和%gt;之前有空格,例如<%=integer。maxValue%>应变为<%=integer.maxValue%>

    来源:

    [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue% > %]
    

    结果:

    &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %>
    
    3 回复  |  直到 15 年前
        1
  •  2
  •   Ahmad Mageed    15 年前

    使用了2个正则表达式。第一个匹配一般的形式,第二个处理内部管道。

    对于XML编码,我使用了在System.Security中找到的一个不起眼的小方法。 SecurityElement.Escape Method . 我在下面的代码中对它进行了充分的限定,以供强调。另一个选择是使用 HttpUtility.HtmlEncode method 但这可能涉及到对System.Web的引用,这取决于您使用它的位置。

    string[] inputs = { @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%= Integer.MaxValue %> %]",
        @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%=Integer.MaxValue %> %]",
        @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%# Integer.MaxValue%> %]",
        @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%#Integer.MaxValue%> %]",
    };
    string pattern = @"(?<open>\[%)(?<content>.*?)(?<close>%])";
    string expressionPattern = @"(?<content>.*?)(?<tag><%(?:[=#]))\s*(?<expression>.*?)\s*%>";
    
    foreach (string input in inputs)
    {
        string result = Regex.Replace(input, pattern, m =>
            m.Groups["open"].Value +
            Regex.Replace(m.Groups["content"].Value, expressionPattern,
                expressionMatch =>
                System.Security.SecurityElement.Escape(expressionMatch.Groups["content"].Value) +
                expressionMatch.Groups["tag"].Value + " " +
                expressionMatch.Groups["expression"].Value +
                " %>"
            ) +
            m.Groups["close"].Value
        );
    
        Console.WriteLine("Before: {0}", input);
        Console.WriteLine("After: {0}", result);
    }
    

    结果:

    Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %> %]
    After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %> %]
    Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%=Integer.MaxValue %> %]
    After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %> %]
    Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%# Integer.MaxValue%> %]
    After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%# Integer.MaxValue %> %]
    Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%#Integer.MaxValue%> %]
    After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%# Integer.MaxValue %> %]
    

    编辑: 如果您不想在最终结果中保留开/关[%%],则将模式更改为:

    string pattern = @"\[%(?<content>.*?)%]";
    

    然后确保删除对 m.Groups["open"].Value m.Groups["close"].Value .

        2
  •  1
  •   ebattulga    15 年前
    private void button1_Click(object sender, EventArgs e)
            {
                Regex reg = new Regex(@"\[%(?<b1>.*)%\]");
                richTextBox1.Text= reg.Replace(textBox1.Text, new MatchEvaluator(f1));
            }
    
            static string f1(Match m)
            {
                StringBuilder sb = new StringBuilder();
                string[] a = Regex.Split(m.Groups["b1"].Value, "<%[^%>]*%>");
                MatchCollection col = Regex.Matches(m.Groups["b1"].Value, "<%[^%>]*%>");
                for (int i = 0; i < a.Length; i++)
                {
                    sb.Append(a[i].Replace("&", "&amp;").Replace("'", "&apos;").Replace("\"", "&quot;").Replace("<", "&lt;").Replace(">", "&gt;"));
                    if (i < col.Count)
                        sb.Append(col[i].Value);
                }
                return sb.ToString();
            }
    

    测试1:

    [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue%> fdas<% hi%> 321%]
    

    结果:

     &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue%> fdas<% hi%> 321
    
        3
  •  0
  •   Community Bayu Bramantya    7 年前

    我认为不使用regex代码就很清楚了。我倾向于为您的规范的每一行编写一个单独的方法(和单元测试),然后将它们链接在一起。

    也见“ When not to use Regex in C# (or Java, C++ etc)"