Reputation: 17627
Can somebody put a regex expression that will:
source:
[% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue% > %]
result:
'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %>
Upvotes: 1
Views: 858
Reputation: 51897
I think the code will be clear without the use of RegEx. I would tend to write a separate method (and unit test) for each line of your spec then chain them together.
See also "When not to use Regex in C# (or Java, C++ etc)"
Upvotes: 0
Reputation: 96477
Used 2 regular expressions. 1st to match the general form, 2nd to deal with the inner plumbing.
For the XML encoding I used an obscure little method found in System.Security: SecurityElement.Escape Method. I fully qualified it in the code below for emphasis. Another option would be using the HttpUtility.HtmlEncode method but that may involve a reference to System.Web depending on where you're using this.
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);
}
Results:
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %> %]
After: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %> %]
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%=Integer.MaxValue %> %]
After: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %> %]
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%# Integer.MaxValue%> %]
After: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%# Integer.MaxValue %> %]
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%#Integer.MaxValue%> %]
After: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%# Integer.MaxValue %> %]
EDIT: if you don't care to preserve the opening/closing [%%] in the final result then change the pattern to:
string pattern = @"\[%(?<content>.*?)%]";
Then be sure to remove references to m.Groups["open"].Value
and m.Groups["close"].Value
.
Upvotes: 2
Reputation: 10981
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("&", "&").Replace("'", "'").Replace("\"", """).Replace("<", "<").Replace(">", ">"));
if (i < col.Count)
sb.Append(col[i].Value);
}
return sb.ToString();
}
Test1:
[% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue%> fdas<% hi%> 321%]
result:
'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue%> fdas<% hi%> 321
Upvotes: 1