• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 495
  • Last Modified:

function to find and replace all image sources in a string, i have code but some bugs outstanding...

hi all, my code below and the bugs

BUG 1 happens when there is no images in the string
BUG 2 happens with the code in the bottom
#################### BUG 1 #################################
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex at System.String.IndexOf(String value, Int32 startIndex, Int32 count, StringComparison comparisonType) at System.String.IndexOf(String value, Int32 startIndex, StringComparison comparisonType) at Functions.ExtractImages(String src, String replacement, Int32 counter, Dictionary`2& imageSources) in e:\netfolder\App_Code\functions.cs:line 114 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

line 114 is :toIndex = src.IndexOf("/>", fromIndex);
line 333 is the function being run
            htmlBody = Functions.ExtractImages(
                Editor1.XHTML, // The HTML source to have <img> tags replaced
                replacement, // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
                firstNumber, // Start with cid:image1 and go up 1 for each <img> tag
                ref imgSources  // The list of strings that will contain the original sources
            );

##################  BUG 2 ###############################
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex at System.String.IndexOf(String value, Int32 startIndex, Int32 count, StringComparison comparisonType) at System.String.IndexOf(String value, Int32 startIndex, StringComparison comparisonType) at Functions.ExtractImages(String src, String replacement, Int32 counter, Dictionary`2& imageSources) in e:\netfolder\App_Code\functions.cs:line 114 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

Open in new window

##################### FUNCTIONS.cs ########################################
    public static string ExtractImages(string src, string replacement, int counter,
            ref Dictionary<string, string> imageSources)
    {
        int toIndex = 0, fromIndex = 0;

        do
        {
            if (toIndex > src.Length) break;
            fromIndex = src.IndexOf("<img", toIndex);
            toIndex = src.IndexOf("/>", fromIndex);
            string part = src.Substring(fromIndex, toIndex - fromIndex + 2);
            string[] tokens = part.Split(new string[] { "\"" }, System.StringSplitOptions.RemoveEmptyEntries);
            imageSources.Add(tokens[1], string.Format(replacement, counter));
            src = src.Replace(tokens[1], string.Format(replacement, counter++));
        } while (true);
        return src;
    }
################## DOCUMENTS.cs ##################################
Dictionary<string, string> imgSources = new Dictionary<string, string>();
            // Start with cid:image1 and go up 1 for each <img> tag
            int firstNumber = 1;
            // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
            string replacement = "cid:image{0}";
            // Run the SourceTextBox contents through the <img> tag replacer, and assign
            // the results to the DestinationTextBox
            htmlBody = Functions.ExtractImages(
                Editor1.XHTML, // The HTML source to have <img> tags replaced
                replacement, // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
                firstNumber, // Start with cid:image1 and go up 1 for each <img> tag
                ref imgSources  // The list of strings that will contain the original sources
            );
            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, "text/html");
            // Now, write the original images and what they were replaced with
            // to a temporary StringBuilder
            foreach (KeyValuePair<string, string> originalSource in imgSources)
            {
                string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);
                LinkedResource image = new LinkedResource(strImageUrl);
                image.ContentId = originalSource.Value.ToString().Replace("cid:", "");
                htmlView.LinkedResources.Add(image);
                              
                Editor1.Text += "<br />Key - " + originalSource.Key;
                Editor1.Text += "<br />Value - " + originalSource.Value;
                Editor1.Text += "<br />ImageURL - " + strImageUrl;
                Editor1.Text += "<br />Imagename - " + originalSource.Value.ToString().Replace("cid:", "");

                firstNumber++;
            }

Open in new window

################ BUG 2 String ###########################

<title> News Letter</title>
<div style="background-position: center; background-repeat: no-repeat; font-family: Arial, Helvetica, sans-serif;
font-size: 12px; color: #333333; background-color: #220000; margin: 0px; padding: 0px;" width="100%">
<table width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
     <tbody>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_top_left.jpg" alt="bg" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_top_right.jpg" alt="bg" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0">
                 <tbody>
                     <tr>
                         <td width="300">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/header_cw.jpg" alt="Construction Works Logo" />
                         </div>
                         </td>
                         <td width="400" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <p style="font-size: 10px;">
                         <a href="javascript:;">Click here for printer friendly version</a>
                         </p>
                         </div>
                         <h2 style="color: #990000;">
                         Type Title Here</h2>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/spacer.jpg" alt="Spacer" width="50" />
             </div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0" bgcolor="#EEEEEE">
                 <tbody>
                     <tr>
                         <td width="20" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_top_left.jpg" alt="bg" />
                         </div>
                         </td>
                         <td width="640" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/shadow2.jpg" align="top" alt="background image 1" />
                         </div>
                         </td>
                         <td width="20" align="right" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_top_right.jpg" alt="bg" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="180" bgcolor="#CCCCCC" align="center" valign="top">
                         <table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td valign="top" align="left">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/images_top_left.jpg" alt="bg" />
                                     </div>
                                     </td>
                                     <td align="center">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/shadow3.jpg" alt="bg" />
                                     </div>
                                     </td>
                                     <td valign="top" align="right">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/images_top_right.jpg" alt="bg" />
                                     </div>
                                     </td>
                                 </tr>
                                 <tr>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                     <td align="center">
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image1.jpg" alt="bg" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image2.jpg" alt="" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image3.jpg" alt="" />
                                     </span>
                                     </p>
                                     </td>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="440">
                         Type Content Here
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                     </tr>
                     <tr>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_bot_left.jpg" alt="" />
                         </div>
                         </td>
                         <td width="660" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="20" align="right">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_bot_right.jpg" alt="" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/shadow.jpg" align="top" alt="background image 2" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF">
                         <div unselectable="ON" contenteditable="false">
                         <table width="700" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td width="340" align="right" valign="top">
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </div>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/spacer.jpg" alt="Spacer" width="50" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50" align="left" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_bot_left.jpg" alt="" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_bot_right.jpg" alt="" />
             </div>
             </td>
         </tr>
     </tbody>
</table>
</div>

Open in new window

0
awilderbeast
Asked:
awilderbeast
  • 4
  • 4
4 Solutions
 
Meir RivkinFull stack Software EngineerCommented:
try this:
public static string ExtractImages(string src, string replacement, int counter, 
            ref Dictionary<string, string> imageSources)
        {
            int toIndex = 0, fromIndex = 0;

            do
            {
                if (toIndex > src.Length) break;
                fromIndex = src.IndexOf("<img", toIndex);
                if (fromIndex == -1) break;
                toIndex = src.IndexOf("/>", fromIndex);
                string part = src.Substring(fromIndex, toIndex - fromIndex + 2);
                string[] tokens = part.Split(new string[] { "\"" }, System.StringSplitOptions.RemoveEmptyEntries);
                imageSources.Add(tokens[1], string.Format(replacement, counter));
                src = src.Replace(tokens[1], string.Format(replacement, counter++));
            } while (true);
            return src;
        }

Open in new window

0
 
awilderbeastAuthor Commented:
thanks thats sorted bug one

bug two has now changed to the below

which i actuall dont think is to do with the mentioned functions

new bug line 344 is
string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);

and if you look at the ouputs that i return the key isnt cid:image4 it has s path
i dont understand how this new error is even occuring, perhaps you can shed some light?

Thanks
#################### NEW BUG CODE ########################
            foreach (KeyValuePair<string, string> originalSource in imgSources)
            {
                string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);
                LinkedResource image = new LinkedResource(strImageUrl);
                image.ContentId = originalSource.Value.ToString().Replace("cid:", "");
                htmlView.LinkedResources.Add(image);
                              
                Editor1.Text += "<br />Key - " + originalSource.Key;
                Editor1.Text += "<br />Value - " + originalSource.Value;
                Editor1.Text += "<br />ImageURL - " + strImageUrl;
                Editor1.Text += "<br />Imagename - " + originalSource.Value.ToString().Replace("cid:", "");

                firstNumber++;
            }

Open in new window

System.Web.HttpException (0x80004005): 'cid:image4' is not a valid virtual path. at System.Web.Util.UrlPath.CheckValidVirtualPath(String path) at System.Web.Util.UrlPath.Combine(String appPath, String basepath, String relative) at System.Web.VirtualPath.Combine(VirtualPath relativePath) at System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) at System.Web.HttpServerUtility.MapPath(String path) at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 344

Open in new window

############################ OUTPUTS ##############################
Key - /documents/mail_images/outer_top_left.jpg
Value - cid:image1
ImageURL - E:\netfolder\documents\mail_images\outer_top_left.jpg
Imagename - image1
Key - /documents/mail_images/outer_top_right.jpg
Value - cid:image2
ImageURL - E:\netfolder\documents\mail_images\outer_top_right.jpg
Imagename - image2
Key - /documents/mail_images/header_cw.jpg
Value - cid:image3
ImageURL - E:\netfolder\documents\mail_images\header_cw.jpg
Imagename - image3
Key - /documents/mail_images/spacer.jpg
Value - cid:image4
ImageURL - E:\netfolder\documents\mail_images\spacer.jpg
Imagename - image4
Key - /documents/mail_images/inner_top_left.jpg
Value - cid:image5
ImageURL - E:\netfolder\documents\mail_images\inner_top_left.jpg
Imagename - image5
Key - /documents/mail_images/shadow2.jpg
Value - cid:image6
ImageURL - E:\netfolder\documents\mail_images\shadow2.jpg
Imagename - image6
Key - /documents/mail_images/inner_top_right.jpg
Value - cid:image7
ImageURL - E:\netfolder\documents\mail_images\inner_top_right.jpg
Imagename - image7
Key - /documents/mail_images/images_top_left.jpg
Value - cid:image8
ImageURL - E:\netfolder\documents\mail_images\images_top_left.jpg
Imagename - image8
Key - /documents/mail_images/shadow3.jpg
Value - cid:image9
ImageURL - E:\netfolder\documents\mail_images\shadow3.jpg
Imagename - image9
Key - /documents/mail_images/images_top_right.jpg
Value - cid:image10
ImageURL - E:\netfolder\documents\mail_images\images_top_right.jpg
Imagename - image10
Key - /documents/mail_images/image1.jpg
Value - cid:image11
ImageURL - E:\netfolder\documents\mail_images\image1.jpg
Imagename - image11
Key - /documents/mail_images/image2.jpg
Value - cid:image12
ImageURL - E:\netfolder\documents\mail_images\image2.jpg
Imagename - image12
Key - /documents/mail_images/image3.jpg
Value - cid:image13
ImageURL - E:\netfolder\documents\mail_images\image3.jpg
Imagename - image13
Key - /documents/mail_images/inner_bot_left.jpg
Value - cid:image14
ImageURL - E:\netfolder\documents\mail_images\inner_bot_left.jpg
Imagename - image14
Key - /documents/mail_images/inner_bot_right.jpg
Value - cid:image15
ImageURL - E:\netfolder\documents\mail_images\inner_bot_right.jpg
Imagename - image15
Key - /documents/mail_images/shadow.jpg
Value - cid:image16
ImageURL - E:\netfolder\documents\mail_images\shadow.jpg
Imagename - image16

Open in new window

0
 
Todd GerbertIT ConsultantCommented:
The RegEx method works, I probably just made a copy/paste error when I posted it.  Using your "BUG 2" string above, I get these results with the RegEx method:

################ BUG 2 String ###########################

<title> News Letter</title>
<div style="background-position: center; background-repeat: no-repeat; font-family: Arial, Helvetica, sans-serif;
font-size: 12px; color: #333333; background-color: #220000; margin: 0px; padding: 0px;" width="100%">
<table width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
     <tbody>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image1" alt="bg" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image2" alt="bg" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0">
                 <tbody>
                     <tr>
                         <td width="300">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image3" alt="Construction Works Logo" />
                         </div>
                         </td>
                         <td width="400" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <p style="font-size: 10px;">
                         <a href="javascript:;">Click here for printer friendly version</a>
                         </p>
                         </div>
                         <h2 style="color: #990000;">
                         Type Title Here</h2>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image4" alt="Spacer" width="50" />
             </div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0" bgcolor="#EEEEEE">
                 <tbody>
                     <tr>
                         <td width="20" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image5" alt="bg" />
                         </div>
                         </td>
                         <td width="640" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image6" align="top" alt="background image 1" />
                         </div>
                         </td>
                         <td width="20" align="right" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image7" alt="bg" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="180" bgcolor="#CCCCCC" align="center" valign="top">
                         <table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td valign="top" align="left">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image8" alt="bg" />
                                     </div>
                                     </td>
                                     <td align="center">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image9" alt="bg" />
                                     </div>
                                     </td>
                                     <td valign="top" align="right">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image10" alt="bg" />
                                     </div>
                                     </td>
                                 </tr>
                                 <tr>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                     <td align="center">
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image11" alt="bg" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image12" alt="" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image13" alt="" />
                                     </span>
                                     </p>
                                     </td>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="440">
                         Type Content Here
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                     </tr>
                     <tr>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image14" alt="" />
                         </div>
                         </td>
                         <td width="660" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="20" align="right">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image15" alt="" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image16" align="top" alt="background image 2" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF">
                         <div unselectable="ON" contenteditable="false">
                         <table width="700" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td width="340" align="right" valign="top">
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </div>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image17" alt="Spacer" width="50" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50" align="left" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image18" alt="" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image19" alt="" />
             </div>
             </td>
         </tr>
     </tbody>
</table>
</div>

Open in new window

/documents/mail_images/outer_top_left.jpg => cid:image1
/documents/mail_images/outer_top_right.jpg => cid:image2
/documents/mail_images/header_cw.jpg => cid:image3
/documents/mail_images/spacer.jpg => cid:image4
/documents/mail_images/inner_top_left.jpg => cid:image5
/documents/mail_images/shadow2.jpg => cid:image6
/documents/mail_images/inner_top_right.jpg => cid:image7
/documents/mail_images/images_top_left.jpg => cid:image8
/documents/mail_images/shadow3.jpg => cid:image9
/documents/mail_images/images_top_right.jpg => cid:image10
/documents/mail_images/image1.jpg => cid:image11
/documents/mail_images/image2.jpg => cid:image12
/documents/mail_images/image3.jpg => cid:image13
/documents/mail_images/inner_bot_left.jpg => cid:image14
/documents/mail_images/inner_bot_right.jpg => cid:image15
/documents/mail_images/shadow.jpg => cid:image16
/documents/mail_images/spacer.jpg => cid:image17
/documents/mail_images/outer_bot_left.jpg => cid:image18
/documents/mail_images/outer_bot_right.jpg => cid:image19

Open in new window


This is the code I used (tweaking it to fit your project should be C# 101):
using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		int counter = FirstNumber - 1;
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			counter++;
			if (OriginalImageSources != null)
				OriginalImageSources.Add(m.Groups[2].Value);
			return m.Value.Replace(m.Groups[2].Value, String.Format(ReplacementFormat, counter)); 
		});
	}
}

Open in new window


I'll try and add some comments to the code to explain how it works in a few minutes.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
awilderbeastAuthor Commented:
hey tgerbert the code you jsut posted, i never got it to work with a dictionary, i didnt know how to split the m.groups[2].value up
0
 
Todd GerbertIT ConsultantCommented:
If put breakpoints in your code you can step through it a line at a time, and just hover the mouse over variables to see their values - m.Groups[2].Value just has "/original/path/to/picture.jpg" in it, you wouldn't want to split it up.

Also, it's important to consult documentation - you can go to http://msdn.microsoft.com/library and  lookup things like String.Format(), Regex.Replace(), delegate keyword, etc.

This is a little verbose, I hope it makes sense, I'm not really getting where you're stuck and where you're good so I just tried to cover all the bases.

DON'T COPY & PASTE THIS CODE - UNDERSTAND IT'S CONCEPTS AND RE-APPLY THEM (do copy/paste the regular expression though, they're such a pain to get right).

using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	// This regular expression looks for and matches an <img /> tag: <img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>
	// The parts in parentheses are rememberd as "Groups", and the first
	// group starts and 0 and is always the entire match - group 1 is
	// the part of the match inside the first set of parentheses, group 2
	// is the second set of parentheses, etc.  In our particular case
	// the second set of parentheses represents the path to the image, e.g. /images/picture.jpg,
	// so if the regular expression matches we can then get the original
	// path from the ".Groups[2].Value" of the match

	// This Regex object is declared at the class-level as a static, this way we only ever use
	// one Regex object (as opposed to creating a new Regex everytime the ReplaceImgTags() method
	// is called) - and this regex is marked with the "Compiled" option which improves performance
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		// The "ReplacementFormat" is expected to look like "cid:image{0}",
		// where {0} will be replaced by a number, so you'd end up with "cid:image1", "cid:image2", etc.
		// If instead ReplacementFormat was "{0}cid:image" you'd end up with "1cid:image", "2cid:image", etc.
		// See how "{0}" is really just a place-holder for where the number goes? This is kinda how
		// String.Format() and related methods work (in fact, later on String.Format() will be used
		// to achieve the desired result).
		// This try/catch block just checks to make sure ReplacementFormat is non-null and contains
		// AT LEAST {0} (if it doesn't contain "{0}" somewhere, String.Format() will throw a fit later)
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		// The FirstNumber parameter lets you start the numbering at whatever number you want
		// So you could START at cid:image17 if you needed to for some reason.
		// The little section of code starting on the "counter++" line will be called for each
		// match (i.e. for each <img /> tag), and since the first line of that code block
		// is counter++, we initially need counter to start off at 1 less than FirstNumber,
		// so that the first time the code section runs it gets incremented to the FirstNumber
		int counter = FirstNumber - 1;

		// The regex.Replace method as used here expects two parameters.
		// The first is the SourceHtml string we're searching for <img /> tags.
		// The second parameter is a method - but instead of actually writing
		// a separate method in this class and just giving that method's name as the parameter,
		// the CONTENTS of that method IS the second parameter - which is done with the "delegate"
		// keyword and is known as an anonymous method (since it is in fact a method without a name)

		// regex.Replace is going to search SourceHtml for every occurence of
		// a sequence of characters that matches the regular expression we defined
		// on line 20 - which means in this case it's going to search SourceHtml
		// for each <img ... /> tag.  Then it's going to replace that <img ... /> tag
		// with whatever is returned by the "embedded" method
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			// Start of "embedded" method (aka Anonymous Method)
			// m is a parameter passed into our function by regex.Replace, it is a "Match" object that
			// contains details about the piece of SourceHtml that matched the expression (i.e. our <img ... /> tag)

			counter++; // Increment the counter (self explanatory)

			// OriginalImageSources is a List<string> (a list of strings) that may or may not have been passed
			// into our ReplaceImgTags method
			if (OriginalImageSources != null)
			{
				// If it is non-null add to the string list 
				OriginalImageSources.Add(m.Groups[2].Value);
			}
			return m.Value.Replace(m.Groups[2].Value, String.Format(ReplacementFormat, counter)); // end of embedded/anonymous method
		});
	}
}

Open in new window

0
 
awilderbeastAuthor Commented:
ok im begining to understand it and im giong to read your comments a few more times (like 20) see if i can get it to sink in

but at the mo  that big string that ive inserted above, i just tried it again and got the below error
System.ArgumentException: An item with the same key has already been added. at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Functions.<>c__DisplayClass1.b__0(Match m) in e:\netfolder\App_Code\functions.cs:line 98 at System.Text.RegularExpressions.RegexReplacement.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat) at System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator) at Functions.ReplaceImgTags(String SourceHtml, String ReplacementFormat, Int32 FirstNumber, Dictionary`2 imageSources) in e:\netfolder\App_Code\functions.cs:line 94 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

Open in new window

0
 
Todd GerbertIT ConsultantCommented:
Rather than trying to throw together a bunch of code you're not really comfortable with yet, try and get a handle on the different pieces.  You can find information on the Dictionary<TKey,TValue> at http://msdn.microsoft.com/en-us/library/xfhwa508.aspx, and I would create a simple console application just to experiment with it.

That error you're getting is pretty straight-forward: each key used in the dictionary must be unique.
// This fails
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("John", "firstName");
dict.Add("John", "middleName");

Open in new window

// This works
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("firstName", "John");
dict.Add("middleName", "John");

Open in new window


Make sense?
0
 
Todd GerbertIT ConsultantCommented:
I seem to be copy & paste impaired - I left off some comments/details in my post above, it should have been this:

using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	// This regular expression looks for and matches an <img /> tag: <img\s+[^>]*src\s*=\s*('|")(.*?)('|")[^>]*/>
	// The parts in parentheses are rememberd as "Groups", and the first
	// group starts and 0 and is always the entire match - group 1 is
	// the part of the match inside the first set of parentheses, group 2
	// is the second set of parentheses, etc.  In our particular case
	// the second set of parentheses represents the path to the image, e.g. /images/picture.jpg,
	// so if the regular expression matches we can then get the original
	// path from the ".Groups[2].Value" of the match

	// This Regex object is declared at the class-level as a static, this way we only ever use
	// one Regex object (as opposed to creating a new Regex everytime the ReplaceImgTags() method
	// is called) - and this regex is marked with the "Compiled" option which improves performance
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		// The "ReplacementFormat" is expected to look like "cid:image{0}",
		// where {0} will be replaced by a number, so you'd end up with "cid:image1", "cid:image2", etc.
		// If instead ReplacementFormat was "{0}cid:image" you'd end up with "1cid:image", "2cid:image", etc.
		// See how "{0}" is really just a place-holder for where the number goes? This is kinda how
		// String.Format() and related methods work (in fact, later on String.Format() will be used
		// to achieve the desired result).
		// This try/catch block just checks to make sure ReplacementFormat is non-null and contains
		// AT LEAST {0} (if it doesn't contain "{0}" somewhere, String.Format() will throw a fit later)
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		// The FirstNumber parameter lets you start the numbering at whatever number you want
		// So you could START at cid:image17 if you needed to for some reason.
		// The little section of code starting on the "counter++" line will be called for each
		// match (i.e. for each <img /> tag), and since the first line of that code block
		// is counter++, we initially need counter to start off at 1 less than FirstNumber,
		// so that the first time the code section runs it gets incremented to the FirstNumber
		int counter = FirstNumber - 1;

		// The regex.Replace method as used here expects two parameters.
		// The first is the SourceHtml string we're searching for <img /> tags.
		// The second parameter is a method - but instead of actually writing
		// a separate method in this class and just giving that method's name as the parameter,
		// the CONTENTS of that method IS the second parameter - which is done with the "delegate"
		// keyword and is known as an anonymous method (since it is in fact a method without a name)

		// regex.Replace is going to search SourceHtml for every occurence of
		// a sequence of characters that matches the regular expression we defined
		// on line 20 - which means in this case it's going to search SourceHtml
		// for each <img ... /> tag.  Then it's going to replace that <img ... /> tag
		// with whatever is returned by the "embedded" method
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			// Start of "embedded" method (aka Anonymous Method)
			// m is a parameter passed into our function by regex.Replace, it is a "Match" object that
			// contains details about the piece of SourceHtml that matched the expression - m will
			// effectively represent the <img /> tag and the pieces we chose to remember with 
			// parentheses in the regular expression

			counter++; // Increment the counter (self explanatory)

			// String.Format is going to find {0} inside the ReplacementFOrmat string
			// and replace it with whatever the value of counter is. e.g. if
			// ReplacementFormat is "cid:image{0}" then replacementText is going to be
			// "cid:image1" for the first <img /> tag, "cid:image2" for the second <img /> tag, etc.
			string replacementText = String.Format(ReplacementFormat, counter);

			string originalImgTag = m.Value; // This is the entire <img src=/blah/blah.jpg height="200" ... /> tag

			// This is just the /blah/blah.jpg part (remember the second set of parentheses in our regular expression
			// corresponds to this part of the <img> tag)
			string originalImgSrc = m.Groups[2].Value;

			// OriginalImageSources is a List<string> (a list of strings) that may or may not have been passed
			// into our ReplaceImgTags method
			if (OriginalImageSources != null)
			{
				// If it is non-null add to the string list the original url
				OriginalImageSources.Add(originalImgSrc);

				// If you wanted to use a Dictionary<string,string> instead of a list, and make the key
				// of the dictionary equal to the replacementText and the value equal to you could write
				// theDictionary.Add(replacementText, originalImgSrc);
				// And then outside of this method could write something like
				// textBox1.Text = theDictionary["cid:image1"];
				// in order to put "/images/pic.jpg" in the text box
			}

			// Search the original <img /> tag for the original img src, and replace
			// it with our new img src - so if the originalImgTag is "<img src='/blah/blah.jpg' height='200' />"
			// then originalImgSrc will be "/blah/blah.jpg", and if you replace "/blah/blah.jpg" with
			// "cid:image1", then newImgTag will end up being "<img src='cid:image1' height='200' />"
			string newImgTag = originalImgTag.Replace(originalImgSrc, replacementText);

			// Return the new <img /> tag to regex.Replace
			return newImgTag; // end of embedded/anonymous method
		});
	}
}

Open in new window

0
 
awilderbeastAuthor Commented:
thanks alot!
begining to understand this now, ive saved the sample to study as i set up my test windows application

thanks again!

if youve got the time bert can you show me what you mean by updating the linq using a dictionary in this post
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26858845.html

ive googled linq and updating with dictionary and i get nothing

thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now