While this has a loop similar to other answers, a minor difference is the selection of the opening and closing tags - instead of calculating modulo 2 to determine if we use an opening or closing tag, I define the pair of tags in an array of size 2:
String[] replaceText = new String[] { "<B>", "</B>" };
Select the element based on a variable iReplacerIndex
replaceText[iReplacerIndex] // Gives either the opening or closing tag
And toggle between the required values by subtracting from 1.
iReplacerIndex = 1 - iReplacerIndex; // If last used was an opening tag,
// then next required is a closing tag
The above also makes it easy to check for mismatched tags - if iReplacerIndex
is not 0 after the loop, then there is a mismatched tag.
The entire code is as follows (its lengthier than it needs to be for clarity):
String sourceText = "My '''random''' text with '''bold''' words.";
int sourceLength = sourceText.Length;
String searchText = "'''";
int searchLength = searchText.Length;
String[] replaceText = new String[] { "<B>", "</B>" };
int iReplacerIndex = 0
, iStartIndex = 0
, iStopIndex = sourceText.Length - 1;
System.Text.StringBuilder sbCache = new System.Text.StringBuilder(sourceText.Length * 2);
do
{
iStopIndex = sourceText.IndexOf(searchText, iStartIndex);
if (iStopIndex == -1)
{
sbCache.Append(sourceText.Substring(iStartIndex, sourceLength - iStartIndex));
}
else
{
sbCache.Append(sourceText.Substring(iStartIndex, iStopIndex - iStartIndex));
sbCache.Append(replaceText[iReplacerIndex]);
iReplacerIndex = 1 - iReplacerIndex;
iStartIndex = iStopIndex + searchLength;
}
} while (iStopIndex != -1);
Console.WriteLine(sbCache.ToString());