Click to See Complete Forum and Search --> : Looping through string variable!
Cipher
09-30-2006, 06:12 PM
Hi all..
I'm making a custom HTMLarea for myself, i'm using special tags i made to modify text formating, like the size and color,......., Just like this forums HTMLarea
then i replace this tags with html tags "<font size=1>some text here</font>" using the Replace method for string, and it works pretty fine, but the problem is that it changes some text that i dont want change, like if i posted a code containge "[]" for looping for example.
So what i want is to loop through the text variable and change each tag i want to change. How can i do that?!
Thank you very much.
drallab
10-02-2006, 09:16 AM
I had written this block of code a few weeks ago to strip out any html tags in the text. _body is the string variable I used to hold the text loaded from a database.
Dim _body as string = "<b>Test</b>. <u>This is </u> a test to remove formatting."
Dim _lt As String = "<"
Dim _gt As String = ">"
Dim _value As Integer = _body.IndexOf(_lt)
Dim _value2 As Integer = _body.IndexOf(_gt, _value) + 1
_body = _body.Replace(_body.Substring(_value, _value2 - _value), "")
You could modify this to replace the text between the tags instead of removing the tags like I did. :)
sirpelidor
10-02-2006, 05:01 PM
Hi, another alternative is to make use the XMLDocument Class (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmldocumentclasstopic.asp).
The load method allow you the load a entire doc into class where the LoadXml method allows you to load just a xml string (you probably more interested in this method...)
for example, if you have the following custom html:
dim htmlString as String = "<font size='1'>some text here</font>"
you can strip it with the following snippet of code:
'method stripe html tag and put inner string
Public Function stripHTMLString(ByVal htmlString As String) As String
Dim xmlString As System.Xml.XmlDocument = New System.Xml.XmlDocument
xmlString.LoadXml(htmlString)
Return xmlString.InnerText
End Function
to use the function (supposed we created an object call HTMLDriver):
Response.write(HTMLDriver.stripHTMLString(htmlString))
for complex custom html tag, u can even use xpath (http://www.w3schools.com/xpath/default.asp) to further customer and control the inner text as well.
see if that helps...
Cipher
10-02-2006, 06:28 PM
i'll show u example of what i tried to do to understand more what i want, but i think now we are getting so close
private string ModifyBody(string Body)
{
//Modify The Size
char[] charBody = Body.ToCharArray();
StringBuilder sb = new StringBuilder();
string strModBody = "";
string strBody = "";
for (int i = 0; i < charBody.Length; i++)
{
sb.Append(charBody[i].ToString());
//strBody = sb.ToString();
if (sb.ToString().IndexOf("") != -1)
{
sb.Replace("]", ">");
sb.Replace("[size=", "<font size=");
sb.Replace("[/size", "</font");
}
}
Body = sb.ToString();//strModBody;
return Body;
}
now this works pretty fine, but the problem is in this tags
"]", ">"
that if there's other tags between the size tag it will change which i dont want to happen.
so, i tried to use this but i dont know how to make it work :)
for (int i = 0; i < charBody.Length; i++)
{
sb.Append(charBody[i].ToString());
strBody = sb.ToString();
if (sb.ToString().IndexOf("[size=") != -1 && sb.ToString().IndexOf("") != -1)
{
//i think this doesnt work fine in the loop
strModBody = strBody.Substring(strBody.IndexOf("") + 7));
strModBody = strModBody.Replace("[size=", "<font size=");
strModBody = strModBody.Replace("", "</font>");
strModBody = strModBody.Replace("]", ">");
}
}
sirpelidor
10-03-2006, 02:16 AM
use of regular expression should be able to do the trick...
suppose we have a string:
aaa]aa
we can set up a method:
//will return orginal parameter if string doesn't match exact systax:
// (something)
private string stripFontTag(string fontString){
//first grab the size attribute...
string sizeValue = Regex.Match(fontString,"[font size='[0-9]']",RegexOptions.IgnoreCase).Value;
sizeValue = sizeValue.Substring(0,1);
//replace the first [
fontString = Regex.Replace(fontString, "[" + Regex.Escape("[") + "]font size='" + sizeValue + "']" ,"<font size='" + sizeValue + "']",RegexOptions.IgnoreCase);
//replace the first ]
fontString = Regex.Replace(fontString, "<font size='" + sizeValue + "'[" + Regex.Escape("]") + "]","<font size='" + sizeValue + "'>",RegexOptions.IgnoreCase);
//replace the closing tag
fontString = Regex.Replace(fontString, "[" + Regex.Escape("[") + "]/font[" + Regex.Escape("]") + "]" ,"</font>",RegexOptions.IgnoreCase);
return fontString;
}//end stripFontTag
(suppose we created an object HTMLdriver) so just go ahead and call the method:
response.write(HTMLdriver.stripFontTag(txtInput.Text);
here's the reference (http://www.regular-expressions.info/dotnetexample.html) for usage with regular expression...
Cipher
10-03-2006, 02:00 PM
I think Regular expressions is so boring, it contains alot of sybmols that will take alot of time to understand, and i think it will work better for validating data than replacing text if string variable. dnt you think?!
isnt there better way to do so with normal substring and replacr methods! :)
sirpelidor
10-03-2006, 03:57 PM
I think Regular expressions is so boring, it contains alot of sybmols that will take alot of time to understand, and i think it will work better for validating data than replacing text if string variable. dnt you think?!
isnt there better way to do so with normal substring and replacr methods! :)
I'm sure there are always alternative. However, I won't be the guy who can judge what is "better" and what is not, I tend to use what I feel is right.
I think the reason I pick regular expression as a solution implementation is because I personally want to match just beyong the char (]) problem. I was more concern of invalid tags (i.e: [font size='3'] ). Using regular expression will allows me to watch out of invalid tag first before i ever try to phase them into html.
I think you can combine methods from string class to accomplish what you wanted, if you use the "look ahead" approach. Meaning you have to prase the entire string into memory first, and then make mutiple trips (read entire string backward and forward) to make sure the logic (tag match, tag attribute match, etc) is in place.
Good luck with you program.
Cipher
10-03-2006, 04:24 PM
Well, thank you, i've been reading in regex for long and i think it will take me long time to do what i want, would you check this out?!
1st, here's the original text
just new function
all new body function
Color Text
the one body function
and here's what i'm trying to do
private string ModifyBody(string Body)
{
//Modify The Size
char[] charBody = Body.ToCharArray();
StringBuilder sb = new StringBuilder();
string strBody = "";
string modBody = "";
for (int i = 0; i < charBody.Length; i++)
{
sb.Append(charBody[i].ToString());
strBody = sb.ToString();
if (strBody.IndexOf("") != -1)
{
// cut the tags and text in tags and put them in other string
modBody = strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("") + 7));
// modify the tags and replace them with html tags
modBody = modBody.Replace("", ">");
// place the new modified string in the sbvariable
sb = sb.Insert(strBody.IndexOf("[size="), modBody);
//sb = sb.Remove(strBody.IndexOf("[size="), (strBody.IndexOf("") + 7));
strBody = sb.ToString();
break;
//aModBody += strBody.Substring(strBody.IndexOf("") + 7)) + "<br>";
sb.Remove(strBody.IndexOf("[size="), (strBody.IndexOf("") + 7));
//strBody = sb.ToString();
//break;
}
}
Body = strBody;
return Body;
}
the problem is in the loop, when i dont use the break; statement i get this error:
Index and length must refer to a location within the string.
Parameter name: length
Exception Details: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
Line 67: modBody = strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("[/size]") + 7));
I dont know why it doesnt continue to the rest of the string!!!!!!!!!!!!!!!!! :confused:
sirpelidor
10-03-2006, 04:56 PM
would this works?
for (int i = 0; i < charBody.Length; i++)
{
sb.Append(charBody[i].ToString());
strBody = sb.ToString();
if (strBody.IndexOf("") != -1)
{
// cut the tags and text in tags and put them in other string
modBody = strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("") + 7));
// modify the tags and replace them with html tags
modBody = modBody.Replace("", ">");
strBody = strBody.Replace(strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("") + 7)), modBody);
}//end if
}//end for
Cipher
10-03-2006, 07:01 PM
Well, it works fine, but i still get the same problem within the loop which in the same line:
modBody = strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("[/size]") + 7));
check out this image i took while trying to debug it, the strBody seems correct, i dont know why the substring method dont work in the loop!!!!!!!!!!!!!
sirpelidor
10-03-2006, 07:14 PM
i dont know why the substring method dont work in the loop!!!!!!!!!!!!!
store the return of the subString method into a variable, instead of putting it in a parameter, see if it changes anything....
1)is it run time error or compile error?
2)what exactly is the error msg again?
Cipher
10-03-2006, 07:26 PM
What exactly do you mean, isnt this what i'm doing?!
modBody = strBody.Substring(strBody.IndexOf("[size="), (strBody.IndexOf("[/size]") + 7));
the modBody is a new string variable i made to store the return of the substring method in.
sirpelidor
10-03-2006, 07:58 PM
looks like the problem is at:
modBody = strBody.Substring(strBody.IndexOf("(strBody.IndexOf("") + 7));[/COLOR]
when your input string has additional 7 or more spaces after [/size], then you are fine. One of your ending string was [/size], therefore + 7 will cause error:
Index and length must refer to a location within the string.
Cipher
10-03-2006, 08:19 PM
hey, i removed the (+7) and still the error remains, i uses so that i can select the end of "[/size ]" tag, other wise it wont select it.
I'm using variable instead now but ofcourse the same problem
string rtg = "[size=";
string ltg = "[/size]";
if (strBody.IndexOf(rtg) != -1 && strBody.IndexOf(ltg) != -1)
{
// cut the tags and text in tags and put them in other string
modBody = strBody.Substring(strBody.IndexOf(rtg), (strBody.IndexOf(ltg) + ltg.Length));
sirpelidor
10-03-2006, 11:21 PM
the problem is still line under:
modBody = strBody.Substring(strBody.IndexOf(rtg), (strBody.IndexOf(ltg) + ltg.Length));
to ignore the big picture and just focus on this line of code, i had copied into a console application and run locally to see what happen...
the following crash at run time:
static void Main(string[] args)
{
string ltg = "";
string rtg = "";
string input = "blah blah blah blah ";
Console.Write(input.Substring(input.IndexOf(ltg),input.IndexOf(rtg) + rtg.length));
Console.ReadLine();
}//end main
then i take those indexof away and put it into a local variable...
and it is crashing at:
static void Main(string[] args)
{
string ltg = "";
string rtg = "";
string input = "blah blah blah blah ";
int start = input.IndexOf(ltg);
int end = input.IndexOf(rtg) + rtg.length;
Console.Write(input.Substring(start,end));
Console.ReadLine();
}//end main
but if you run in debug mode, you'll see start=5, and end = 34.
now look at my input.length, it says it has size 34....
but the length starting from to end with is only 29, so 34 will be out of bounce.
hope that works for you,
good luck.
Cipher
10-04-2006, 06:46 AM
I dont know when this is going to finish :) , but i tried this and gave me the same error, plus this's how the first line changed to be
<font size=7>just new functio[size= 5]all new body function[/ size]
and you will notice that it didnt replace the [/ size] tag coz it wasnt included in the substring, and you'll notice in the image that it works pretty fine with the same line :confused:
Cipher
10-04-2006, 09:53 AM
check this out
I think its not just about the length parameter (end), it's the whole range from start to end, because i tried to make the start variable 0 for the whole loop and it worked without no error.
But still the problem remians which will change for example "]", ">" tags for the whole string varibale which i dont want.
sirpelidor
10-04-2006, 12:07 PM
I dont know when this is going to finish :)
I think maybe you should reconsider and give my regular express function a try. Especially I helped you save over 50% lines of codes. :P
My function is working as long as your incoming format is <size='(number)'>, not <size= (number)>.
I'm sorry I couldn't be much help with your substring, replace combine with for loop approach as it wasn't my first choice to begin with.
Good luck on solving that problem.
Cipher
10-04-2006, 12:43 PM
Thank you alot, you were so helpful, i think i'll begin trying regex and wish i be able to solve it.
sirpelidor
10-04-2006, 12:50 PM
i think i'll begin trying regex and wish i be able to solve it.
yea, I myself is very weak with regular express also, and I had to use this link (http://www.regular-expressions.info/reference.html) in order to figure out what sytax is needed in order to come up with your <size> match. I hope you'll find that helpful as well.
Good luck.
Cipher
10-04-2006, 07:00 PM
Man, i think i found it, i think the problem was that i misunderstood the length argument in substring method
the length is the number of characters in the substring, and what i was doing that i was giving it the double size of the string i wanted, like this:
int end = (strBody.IndexOf(ltg) + ltg.Length);
which will be the index of the last tag in the varibale so it will count the whole string, but like this it works pretty fine:
rtg = "[size=";
ltg = "[/size]";
int start = strBody.IndexOf(rtg);//0;
int end = ((strBody.IndexOf(ltg) + ltg.Length) - start);
Thank you sirpelidor alot for your help
sajjad27s
10-05-2006, 02:25 AM
I am not seeing any bug in this code.
Cipher
10-05-2006, 06:19 AM
you've got to read the whole forum to know what's wrong :)