Background: I've wrote a small library that is able to create asp.net controls from a string.
Sample text:
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
{{asp:hyperlink|NavigateUrl="/faq.aspx";Text="FAQ";}}
{{codesample|Text="FAQ";}}
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
I got my initial help here. I've expanded the code with some reflection to gain full flexibility to be able to render WebControls and UserControls. Works fine so far, for every usercontrol I've tested. I'm now facing the problem, that the parsing for my property key-value is not flexible enough to support arbitrary multine content.
This is part of the code that I'm using for the string operations:
substring = substring.Replace("\\"", "\""); //substring is the string containing lore ipsum
substring = substring.Replace(""", "\"");
Regex r = new Regex("{{(?<single>([a-z0-9:]*))\\|((?<pair>([a-z0-9:]*=\"[a-z0-9.:/?_~=]*\";))*)}}", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Match m = r.Match(substring);
if (m.Success)
{
Dictionary<string, string> properties = new Dictionary<string, string>();
foreach (Capture cap in m.Groups["pair"].Captures)
{
string key = cap.ToString().Substring(0, cap.ToString().IndexOf("="));
if (!properties.ContainsKey(key))
{
string value = cap.ToString().Substring(cap.ToString().IndexOf("=\"") + 2);
value = value.Substring(0, value.Length - 2);
properties.Add(key, value);
}
}
MethodInfo dynamicRenderControl = null;
String controlString = m.Groups["single"].Value.ToLower();
}
(The string comes from a database. It was previously set in my CMS. I have left our the code for getting groups of {{FOO|BAR="Foo2";}})
This is what the regex does: Example:
{{asp:hyperlink|NavigateUrl="/faq.aspx";Text="FAQ";}}
It parses "asp:hyperlink" into m.Groups["single"]. It is the string I need for mapping to a specific control type.
After the '|' I have the list of properties that will be captured into m.Groups["pair"].Captures.
This all works fine, but not for multiline text or more complex text. E.g.
{{codesample|Text="using System.Text;<br />\r\nusing System.Bla;";}}
This is where my code breaks.
Question:
How must I adjust the regex to make it working for multiline text, that starts with \" and ends with \"; altough there might also be \" inside that text? Or is that not possible with regex?
Edit: I've been thinking. Its not possible to achieve what I want with regex, because a \" in the text automatically breaks the code. I'm switching the outer delimeter to the CDATA syntax XML uses. Wikientry for CDATA
"<![CDATA[This is my content]]>";
This means that each entry looks like this:
{{codesample|Text="<![CDATA[this is text on the first line<br />\r\nthis is text on the second line]]>";}}
Where the beginning of the value is
"<![CDATA[
and the end
]]>";
I've been trying to write this regex myself but I failed. Could anyone assist me with this one?