using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
/*
Code written by A.Sivakumar
*/
namespace TextReplaceIO
{
/// <summary>
/// Class can be used for replacing String based on the following conditions.
/// 1.Find a Specific string and replace it with another string
/// 2.Find a Specific string and replace it with another string, if the strings are in between specified block
/// 3.Replace entire String within specified string
/// 4.Replace entire String withing specified string if the strings are in between specified block
/// 5.Replace a string if and only if it is found before or after a specific string.
/// </summary>
public class StringReplaceHelper
{
bool replaceBeforeSpecifiedString = false;
SubStringType replaceCondition = SubStringType.None;
//Used when we need to replace entire string in between specified strings, if the contents are inside specific
//blocks.
string finalString = null;
#region Properties
/// <summary>
/// The default value is false and so the string will be replaced only after the specified substring.
/// </summary>
[DefaultValue(false), Description("Use this property, if you want to replace some strings which needs to be searched and replaced only before or after some specified string")]
public bool ReplaceBeforeSpecifiedString
{
get
{
return this.replaceBeforeSpecifiedString;
}
set
{
this.replaceBeforeSpecifiedString = value;
}
}
[DefaultValue(typeof(SubStringType), "None")]
private SubStringType ReplaceCondition
{
get
{
return this.replaceCondition;
}
set
{
this.replaceCondition = value;
}
}
#endregion
#region Enum
public enum SubStringType
{
/// <summary>
/// There is no substring to be specified. Replacing should be made without any condition, for the string that needs to be replaced
/// </summary>
One,
/// <summary>
/// SubStrings needs to be searched and replaced in between specified strings.
/// </summary>
StartAndEnd,
/// <summary>
/// SubStrings needs to be searched and replaced, before or after specified string.
/// </summary>
StartOnly,
/// <summary>
/// Replace the entire substring within specified strings.
/// </summary>
ReplaceSubString,
None
}
#endregion
#region PrivateMethod
/// <summary>
/// Condition to be checked before the replacing of Strings.
/// </summary>
/// <param name="strFileSubStringVal"></param>
private void CheckForReplaceCondition(string[] strFileSubStringVal, string endsWith, string toBeReplaced)
{
int subStringSize = strFileSubStringVal.Length;
if (subStringSize >= 2 && endsWith != String.Empty && toBeReplaced !=String.Empty)
{
this.ReplaceCondition = SubStringType.StartAndEnd;
}
else if (subStringSize >= 2 && endsWith == String.Empty)
{
this.ReplaceCondition = SubStringType.StartOnly;
}
else if (subStringSize >= 2 && endsWith == String.Empty && toBeReplaced == null)
{
this.ReplaceCondition = SubStringType.ReplaceSubString;
}
else if (subStringSize == 1 && endsWith == String.Empty)
{
this.replaceCondition = SubStringType.One;
}
else
{
this.ReplaceCondition = SubStringType.None;
}
}
#endregion
#region PublicMethod
public string ReplaceString(string strFile, string toBeReplaced,string replaceWith)
{
return ReplaceStringWithCondition(String.Empty,String.Empty,strFile,toBeReplaced, replaceWith);
}
/// <summary>
/// Replaces the entire strings between specified strings.
/// </summary>
/// <param name="startsWith">The start string from which the strings should be replaced</param>
/// <param name="endsWith">The end string, until which the strings will be replaced</param>
/// <param name="strFile">String to be manipulated, Usually we will read strings from the file and pass here to replace some of the
/// contents from the string based on the 'startsWith' and 'endsWith' parameters.
/// </param>
/// <param name="replaceWith">The string that needs to be replaced based on the startsWith and endsWith Parameters</param>
/// <returns>Returns the string after replacing the strings between specified parameters in the <paramref name="=strFile"/>. If no strings are replaced, returns String.Empty</returns>
public string ReplaceStringsBetween(string startsWith, string endsWith, string strFile, string replaceWith)
{
string strFinal=ReplaceStringWithCondition(startsWith, endsWith, strFile, null, replaceWith);
return strFinal;
}
//TODO:- This method should further modify like getting LeftString,OriginalString,RightString, from another methods and just we need to call
//replaced string alone inside this method.
/// <summary>
/// Replaces the entire strings between specified strings. Where the specified strings are within specified limits.
/// </summary>
/// <param name="startBlock">Begin Block from where the search starts for the StartsWith and endsWithString</param>
/// <param name="endBlock">End Block until which the search starts for the StartsWith and endsWith String</param>
/// <param name="startsWith">The replacement of string starts after this string.</param>
/// <param name="endsWith">The end string, until which the strings will be replaced</param>
/// <param name="strFile">String to be manipulated, Usually we will read strings from the file and pass here to replace some of the
/// contents from the string based on the 'startsWith' and 'endsWith' parameters.</param>
/// <param name="replaceWith">The string that needs to be inserted between startsWith and endsWith Parameters</param>
/// <returns></returns>
public string ReplaceStringBetweenWithCondition(string startBlock, string endBlock, string startsWith, string endsWith, string strFile, string replaceWith)
{
int startBlockIndex = strFile.IndexOf(startBlock);
int endBlockIndex = 0;
if (startBlockIndex >= 0)
{
endBlockIndex = strFile.IndexOf(endBlock, startBlockIndex);
}
if (startBlockIndex >= 0 && endBlockIndex >= 0 && endBlockIndex >= startBlockIndex)
{
int subStringLength = (endBlockIndex - startBlockIndex) + endBlock.Length;
string leftString = strFile.Substring(0, startBlockIndex);
string strFileSubString = strFile.Substring(startBlockIndex, subStringLength);
string replacedString = ReplaceStringsBetween(startsWith, endsWith, strFileSubString, replaceWith);
int rightStringIndex = endBlockIndex + endBlock.Length;
string rightString = strFile.Substring(rightStringIndex, strFile.Length - rightStringIndex);
//Final String after replacing the string. The right String is not included, as the final string will not
//include the string which is not yet checked for the conditions.
finalString = finalString + leftString + replacedString;
int startBlockIndex1 = rightString.IndexOf(startBlock);
int endBlockIndex1 = 0;
if (startBlockIndex1 >= 0)
{
endBlockIndex1 = rightString.IndexOf(endBlock, startBlockIndex1);
}
if (startBlockIndex1 >= 0 && endBlockIndex1 >= 0 && endBlockIndex1 >= startBlockIndex1)
{
//Recursive call for searching and replacing if any more contennts are found in the rest of the string(i.e the rightString)
ReplaceStringBetweenWithCondition(startBlock, endBlock, startsWith, endsWith, rightString, replaceWith);
}
else
{
finalString = finalString + rightString;
}
}
else
{
finalString = finalString + strFile;
}
return finalString;
}
/// <summary>
/// Replace specific strings with another string only if the string that needs to be replaced is present within specified strings.
/// </summary>
/// <param name="startsWith">The start string from which the strings should be replaced should be searched</param>
/// <param name="endsWith">The end string until which the strings should be replaced should be searched. If this parameter is String.Empty, then
/// the substring will search only based on the startsWith Parameter</param>
/// <param name="strFile">String to be manipulated, Usually we will read strings from the file and pass here to replace some of the
/// contents from the string based on the 'startsWith' and 'endsWith' parameters</param>
/// <param name="toBeReplaced">String that needs to be replaced if it is between the 'startsWith' and 'endsWith' parameter. If this Parameter equals String.Empty, then
/// the entire substring between 'startsWith' and 'endsWith' Parameter will be replaced.</param>
/// <param name="replaceWith">String that will be replacing the 'toBeReplaced' parameter</param>
/// <returns></returns>
public string ReplaceStringWithCondition(string startsWith, string endsWith, string strFile, string toBeReplaced, string replaceWith)
{
string[] startsWithVal = new string[1];
string strFinal = String.Empty;
startsWithVal[0] = startsWith;
string[] strFileSubStringVal = strFile.Split(startsWithVal, StringSplitOptions.None);
int subStringSize = strFileSubStringVal.Length;
//Calling this method is essential as the we manuipulate the files based on the conditions checked in this method.
CheckForReplaceCondition(strFileSubStringVal, endsWith, toBeReplaced);
switch (this.ReplaceCondition)
{
case SubStringType.One:
{
if (toBeReplaced != null && strFile.IndexOf(toBeReplaced) > 0)
{
strFinal = strFile.Replace(toBeReplaced, replaceWith);
}
else
{
strFinal = strFile;
}
break;
}
case SubStringType.ReplaceSubString:
case SubStringType.StartAndEnd:
{
for (int i = 1; i < subStringSize; i++)
{
//if there is no end string in the specified substring, then there will not be any replacement of strings.
if (strFileSubStringVal[i].IndexOf(endsWith) > 0)
{
string[] strEndVal ={ endsWith };
string[] toBeSearched = strFileSubStringVal[i].Split(strEndVal, StringSplitOptions.None);
string endString = String.Empty;
for (int j = 1; j < toBeSearched.Length; j++)
{
endString = endString + endsWith + toBeSearched[j];
}
//When the entire string within Start and End String needs to be replaced
if (toBeReplaced == null)
{
strFileSubStringVal[i] = startsWith + toBeSearched[0].Replace(toBeSearched[0], replaceWith) + endString;
}
//When only some of the substring needs to be replaced within specified strings
else
{
strFileSubStringVal[i] = startsWith + toBeSearched[0].Replace(toBeReplaced, replaceWith) + endString;
}
}
else
{
//Since, we split using the startsWith Value it is important to join the string with the array, even when there is no replacement
strFileSubStringVal[i] = startsWith + strFileSubStringVal[i];
}
}
for (int i = 0; i < subStringSize; i++)
{
strFinal = strFinal + strFileSubStringVal[i];
}
break;
}
case SubStringType.StartOnly:
{
if (this.ReplaceBeforeSpecifiedString)
{
if (strFileSubStringVal[0].IndexOf(toBeReplaced) > 0)
{
strFileSubStringVal[0] = strFileSubStringVal[0].Replace(toBeReplaced, replaceWith);
}
}
else if (strFileSubStringVal[1].IndexOf(toBeReplaced) > 0)
{
strFileSubStringVal[1] = strFileSubStringVal[1].Replace(toBeReplaced, replaceWith);
}
strFinal = strFileSubStringVal[0] + startsWith + strFileSubStringVal[1];
break;
}
case SubStringType.None:
{
strFinal = strFile;
break;
}
}
return strFinal;
}
}
#endregion
}