Link to WinRT XAML code optimization I need a method which will parse text to RichTextBlock-compatible XAML markup with clickable links.

Example:

Input: 

"Hello, check new service for students! Check edusty.ru and http://edusty.ru/test?text1=abc&amp;args=123 sites. Check edusty.ru/privacy.html to read privacy policy."


Output:

&lt;Paragraph xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" TextAlignment="Left" FontSize="20"  FontWeight="Normal" FontStyle="Normal" FontStretch="Normal" &gt;
     &lt;Run Text="Hello, check new service for students! Check "/&gt; 
     &lt;Hyperlink NavigateUri="http://edusty.ru"&gt;edusty.ru&lt;/Hyperlink&gt; 
     &lt;Run Text=" and "/&gt;
     &lt;Hyperlink NavigateUri="http://edusty.ru/test?text1=abc&amp;amp;args=123"&gt;http://edusty.ru/test?text1=abc&amp;amp;args=123&lt;/Hyperlink&gt; 
     &lt;Run Text=" sites. Check "/&gt;
     &lt;Hyperlink NavigateUri="http://edusty.ru/privacy.html"&gt;edusty.ru/privacy.html&lt;/Hyperlink&gt;
     &lt;Run Text=" to read privacy policy."&gt;&lt;/Run&gt;
&lt;/Paragraph&gt;


I wrote this method:

public static string ParseLinksToXaml(this string source)
        {
            var transformedText = Regex.Replace(source,
                @"((https?:\/\/)?(ftps?:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/\S*)?)",
                @"""/&gt; &lt;Hyperlink NavigateUri=""$1""&gt;$1&lt;/Hyperlink&gt; &lt;Run Text=""", RegexOptions.IgnoreCase);
            transformedText = WebUtility.HtmlEncode(transformedText);
            var matches = Regex.Matches(transformedText, @"&amp;quot;\/&amp;gt;\s&amp;lt;Hyperlink NavigateUri=&amp;quot;.*?&amp;quot;&amp;gt;|&amp;lt;\/Hyperlink&amp;gt;\s&amp;lt;Run Text=&amp;quot;");
            foreach (var match in matches)
                transformedText = transformedText.Replace(match.ToString(), WebUtility.HtmlDecode(match.ToString()));

            matches = Regex.Matches(transformedText, @"NavigateUri=\""(.*?)""&gt;");
            foreach (Match match in matches)
            {
                var link = match.Groups[1].ToString();
                link = link.Replace("&amp;", "&amp;amp;");
                link = link.Contains("://") ? link : "http://" + link;
                transformedText = transformedText.ReplaceFirst("\"" + match.Groups[1] + "\"", "\"" + link + "\"");
            }
            var xaml = @"&lt;Paragraph xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextAlignment=""Left"" FontSize=""20""  FontWeight=""Normal"" FontStyle=""Normal"" FontStretch=""Normal"" &gt;
                                    &lt;Run Text=""" + transformedText + @"""&gt;&lt;/Run&gt;&lt;/Paragraph&gt;";
            return xaml;
        }


It works, but the code really looks bad. Can anyone help rewrite/optimize this?
Whenever you're concatenating strings inside a loop's body, +-concatenation should be ruled out; transformedText would be a StringBuilder instance, to which each iteration would Append.

However XAML is a subset of XML; as such, there is no reason to treat your output as purely strings: using the classes in the System.Linq.Xml namespace (otherwise known as "Linq-to-Xml"), you can rewrite this in a much more elegant and object-oriented way.

Extending System.String like this is a bit overkill, too. I'm not sure I'd like working in a code base where every single string out there has this ParseLinksToXaml extension method: that functionality is very specialized, and IMO deserves its own class where the client code is actually explicit about what's going on:

var parser = new StringLinksToXamlConverter();
var xaml = parser.ParseLinksToXaml(myString);


The string-building stuff going on under the hood should be an implementation detail - the returned value would be potentially much more useful to the client code if an XDocument was returned, leaving it up to the client code to query or output as a string.