How to replace multiple texts in a file in c#? - c#

I am automating a process using c#. My script would look like below,
UPDATE Table
SET param_val = REPLACE(param_val,'Proxy430/','Proxy440/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE (param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%';
For every month, we will upgrade the version like 44 in place of 43 and 43 in place of 42 and run this script. To automate, i've written C# code and used below code
string text = File.ReadAllText(filePath);
text.Replace(oldvale, newvalue);
File.WriteAllText(filepath, text);
But, issue is it can replace one word only. How to replace two texts in a file. In my case, Proxy430 should be replaced as Proxy440 and Proxy440 into Proxy450 in single shot.
How to achieve this?

If you call replace in the right order you can accomplish two replacements on a single line.
string TestString = #"UPDATE Table
SET param_val = REPLACE(param_val, 'Proxy430/', 'Proxy440/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE(param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%'; ";
const string oldFrom = "Proxy430";
const string oldTo = "Proxy440";
const string newFrom = "Proxy440";
const string newTo = "Proxy450";
string result = TestString.Replace(newFrom, newTo).Replace(oldFrom, oldTo);
Console.WriteLine(result);
The output is:
UPDATE Table
SET param_val = REPLACE(param_val, 'Proxy440/', 'Proxy450/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE(param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%';

The problem is you don't assign the return value of Replace method. Replace doesn't modify this string it returns replaced string.
Change it like this:
text = text.Replace(oldvale, newvalue);
Here's a fiddle.

If the things are really sequential numerically, you can do something like this:
string text = File.ReadAllText(filePath);
for (int i=lowestVersion; i < highestVersion; i++)
{
var oldValue = i.ToString() + "0";
var newValue = (i+1).ToString() + "0";
text.Replace(oldValue , newvalue);
}
File.WriteAllText(filepath, text);

You can create a custom method for this.
private void MultipleReplace(string text, string[] oldValues, string[] newValues)
{
for (int i = 0; i < old.Length; i++)
{
text = text.replace(oldValues[i], newValues[i]);
}
}
You need to consider the order of replacements, because once you replace Proxy430 by Proxy440, you can no longer replace Proxy440 by Proxy450, because that'll also replace the values updated in the previous iteration.
Example:
string text = File.ReadAllText(filePath);
string[] oldValues = { "Proxy440", "Proxy430" };
string [] newValues = { "Proxy450", "Proxy440" };
MultipleReplace(text, oldValues, newValues);
File.WriteAllText(filepath, text);

Related

Sorting a given string - What is wrong with my IF Contains block?

Super new to C# apologize upfront. My goal is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. Numbers can be from 1 to 9. So 1 will be the first word (not 0).
My plan of attack is to split the string, having one variable of int data-type (int lookingForNum) and the other variable turning that into a String data-type(string stringLookingForNum), then for each loop over the array looking to see if any elements contain string stringLookingForNum, if they do I add it to an emptry string variable, lastly add 1 to int variable lookingForNum. My issue seems to be with the if statement with the Contains method. It will not trigger the way I currently have it written. Hard coding in if (word.Contains("1")) will trigger that code block but running it as written below will not trigger the if statement.Please can anyone tell my WHY!?!? I console.log stringLookingForNum and it is for sure a string data type "1"
This noobie would appreciate any help. Thanks!
string testA = "is2 Thi1s T4est 3a"; //--> "Thi1s is2 3a T4est"
string[] arrayTestA = testA.Split(' ');
string finalString = string.Empty;
int lookingForNum = 1; //Int32
foreach (string word in arrayTestA){
string stringLookingForNum = lookingForNum.ToString();
//Don't understand why Contains is not working as expected here)
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
}
lookingForNum++;
}
you need this - look for the string with 1, the look for the string with 2 etc. Thats not what you are doing
you look at the first string and see if it contains one
then look at the second one and see if it contains 2
....
int lookingForNum = 1;
while(true){ // till the end
string stringLookingForNum = lookingForNum.ToString();
bool found = false;
foreach (string word in arrayTestA){
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
found = true;
break;
}
}
if(!found) break;
lookingForNum++;
}
To sort you should simply use OrderBy, and since you need to sort by number inside a word - just Find and extract a number from a string
string testA = "is2 Thi1s T4est 3a";
var result = testA.Split().OrderBy(word =>
Int32.Parse(Regex.Match(word, #"\d+").Value));
Console.WriteLine(string.Join(" ", result));

SSIS C# Script Task: How to match/replace pattern with increment on a large XML file

There are other similar questions that have been asked and answered, but none of those answers work in what I'm trying to do, or there isn't enough information for me to know how to implement it in my own code. I've been at it for two days and now must ask for help.
I have a script task in an SSIS package where I need to do a match and replace on a large XML file that contains thousands of Record Identifier tags. Each one contains a number. I need those numbers to be consecutive and increment by one. For example, within the xml file, I am able to find tags that appear like this:
<ns1:recordIdentifier>1</ns1:recordIdentifier>
<ns1:recordIdentifier>6</ns1:recordIdentifier>
<ns1:recordIdentifier>223</ns1:recordIdentifier>
<ns1:recordIdentifier>4102</ns1:recordIdentifier>
I need to find and replace those tags with consecutive increments like so:
<ns1:recordIdentifier>1</ns1:recordIdentifier>
<ns1:recordIdentifier>2</ns1:recordIdentifier>
<ns1:recordIdentifier>3</ns1:recordIdentifier>
<ns1:recordIdentifier>4</ns1:recordIdentifier>
The code I have so far is causing all the numbers to be "1" with no incrementation.
I've tried dozens of different methods, but nothing has worked yet.
Any ideas as to how I can modify the below code to increment as desired?
public void Main()
{
string varStart = "<ns1:recordIdentifier>";
string varEnd = "</ns1:recordIdentifier>";
int i = 1;
string path = Dts.Variables["User::xmlFilename"].Value.ToString();
string outPath = Dts.Variables["User::xmlOutputFile"].Value.ToString();
string ptrn = #"<ns1:recordIdentifier>\d{1,4}<\/ns1:recordIdentifier>";
string replace = varStart + i + varEnd;
using (StreamReader sr = File.OpenText(path))
{
string s = "";
while ((s = sr.ReadLine()) != null && i>0)
{
File.WriteAllText(outPath, Regex.Replace(File.ReadAllText(path),
ptrn, replace));
i++;
}
}
}
You were on the right path with the Replace method, but will need to use the MatchEvaluater parameter when you increment.
string inputFile = Dts.Variables["User::xmlFilename"].Value.ToString();
string outPutfile = Dts.Variables["User::xmlOutputFile"].Value.ToString();
string fileText = File.ReadAllText(inputFile);
//get any number between elements
Regex reg = new Regex("<ns1:recordIdentifier>[0-9]</ns1:recordIdentifier>");
string xmlStartTag = "<ns1:recordIdentifier>";
string xmlEndTag = "</ns1:recordIdentifier>";
//assuming this starts at 1
int incrementInt = 1;
fileText = reg.Replace(fileText, tag =>
{ return xmlStartTag + incrementInt++.ToString() + xmlEndTag; });
File.WriteAllText(outPutfile, fileText);

Append string and format Array Values

I have a array with values and want to append a link to all the values of array assign back the value to same array.
string [] files = null; // will contain array of string values
string[] attachmentFilePath = files;
string[] attachmentFileName = files;
I want to append "http://www.google.com" with every value in the files array and assign it to attachmentFilePath.
I have tried a lot using string.format("google.com",files[index])
for(var i = 0; i<files.count();i++)
{
files[index] = string.format("http://www.google.com",files[index]);
}
tried a lot but some or the other way the code gives error or index out of bounds or null reference exception.
I need the string to appended like 'http://www.google.com/files.value'
Can anyone help me out ?
Using string.Format requires the string to be in the proper format for formatting:
string.Format("some string with place holder: {0}","some string to put");
If your string does not have the placeholders (as in your case) it doesn't do anything. Read more about string.Format
Solutions:
Simple for loop:
var yourString = "http://www.google.com/";
var attachmentFilePath = new string[files.Length];
for(int i = 0; i < files.Length; i++)
{
attachmentFilePath[i] = yourString + files[i];
}
Linq:
var yourString = "http://www.google.com/";
var attachmentFilePath = files.Select(s => yourString + s).ToArray();
And of course you can correctly use string.Format to any of these two solutions where appending the strings. Just see it is has the place holder in the place you want
You can accomplish the task at hand with something along the lines of:
string[] attachmentFilePath = files.Select(x => $"http://www.google.com/{x}")
.ToArray();

How to implement "Find, Replace, Next" in a String on C#?

I'm searching for a solution to this case:
I have a Method inside a DLL that receive a string that contains some words as "placeholders/parameters" that will be replaced by a result of another specific method (inside dll too)
Too simplificate: It's a query string received as an argument to be on a method inside a DLL, where X word that matchs a specifc case, will be replaced.
My method receive a string that could be like this:
(on .exe app)
string str = "INSERT INTO mydb.mytable (id_field, description, complex_number) VALUES ('#GEN_COMPLEX_ID#','A complex solution', '#GEN_COMPLEX_ID#');"
MyDLLClass.MyMethod(str);
So, the problem is: if i replace the #GEN_COMPLEX_ID# on this string, wanting that a different should be on each match, it not will happen because the replaced executes the function in a single shot (not step by step). So, i wanna help to implement this: a step by step replace of any text (like Find some word, replace, than next ... replace ... next... etc.
Could you help me?
Thanks!
This works pretty well for me:
string yourOriginalString = "ab cd ab cd ab cd";
string pattern = "ab";
string yourNewDescription = "123";
int startingPositionOffset = 0;
int yourOriginalStringLength = yourOriginalString.Length;
MatchCollection match = Regex.Matches(yourOriginalString, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
foreach (Match m in match)
{
yourOriginalString = yourOriginalString.Substring(0, m.Index+startingPositionOffset) + yourNewDescription + yourOriginalString.Substring(m.Index + startingPositionOffset+ m.Length);
startingPositionOffset = yourOriginalString.Length - yourOriginalStringLength;
}
If what you're asking is how to replace each placeholder with a different value, you can do it using the Regex.Replace overload which accepts a MatchEvaluator delegate, and executes it for each match:
// conceptually, something like this (note that it's not checking if there are
// enough values in the replacementValues array)
static string ReplaceMultiple(
string input, string placeholder, IEnumerable<string> replacementValues)
{
var enumerator = replacementValues.GetEnumerator();
return Regex.Replace(input, placeholder,
m => { enumerator.MoveNext(); return enumerator.Current; });
}
This is, of course, presuming that all placeholders look the same.
Pseudo-code
var split = source.Split(placeholder); // create array of items without placeholders
var result = split[0]; // copy first item
for(int i = 1; i < result.Length; i++)
{
bool replace = ... // ask user
result += replace ? replacement : placeholder; // to put replacement or not to put
result += split[i]; // copy next item
}
you should use the split method like this
string [] placeholder = {"#Placeholder#"} ;
string[] request = cd.Split(placeholder, StringSplitOptions.RemoveEmptyEntries);
StringBuilder requetBuilding = new StringBuilder();
requetBuilding.Append(request[0]);
int index = 1;
requetBuilding.Append("Your place holder replacement");
requetBuilding.Append(request[index]);
index++; //next replacement
// requetBuilding.Append("Your next place holder replacement");
// requetBuilding.Append(request[index]);

String.Replace doesn't work with a php file?

Why the code below doesnt work ?
string Tmp_actionFilepath = #"Temp\myaction.php";
// change the id and the secret code in the php file
File.Copy(#"Temp\settings.php", Tmp_actionFilepath, true);
string ActionFileContent = File.ReadAllText(Tmp_actionFilepath);
string unique_user_id = textBox5.Text.Trim();
string secret_code = textBox1.Text.Trim();
ActionFileContent.Replace("UNIQUE_USER_ID", unique_user_id);
ActionFileContent.Replace("SECRET_CODE", secret_code);
File.WriteAllText(Tmp_actionFilepath, ActionFileContent);
Here is the content of setting.php
<?php
session_start();
$_SESSION["postedData"] = $_POST;
/////////////////////////////////////////////////////////
$_SESSION["uid"] = "UNIQUE_USER_ID";
$_SESSION["secret"] = "SECRET_CODE";
/////////////////////////////////////////////////////////
function findThis($get){
$d = '';
for($i = 0; $i < 30; $i++){
if(file_exists($d.$get)){
return $d;
}else{
$d.="../";
}
}
}
$rootDir = findThis("root.cmf");
require_once($rootDir."validate_insert.php");
What is wrong with the code above ? After compiling the code in c#, i noticed the file myaction.php is created, but the values : UNIQUE_USER_ID and SECRET_CODE doesn't change, I tried also to copy/paste these values to make sure they are same. But the code always doesn't work
String.Replace returns a new string as strings are immutable. It does not replace the string you are calling it on.
You should replace:
ActionFileContent.Replace("UNIQUE_USER_ID", unique_user_id);
ActionFileContent.Replace("SECRET_CODE", secret_code);
with:
ActionFileContent = ActionFileContent.Replace("UNIQUE_USER_ID", unique_user_id);
ActionFileContent = ActionFileContent.Replace("SECRET_CODE", secret_code);
On top of that you should really change your variable names so they follow the regular C# naming conventions (i.e. use actionFileContent instead of ActionFileContent).
you have to set the result of the replace string method on a string.
string Tmp_actionFilepath = #"Temp\myaction.php";
// change the id and the secret code in the php file
File.Copy(#"Temp\settings.php", Tmp_actionFilepath, true);
string actionFileContent = File.ReadAllText(Tmp_actionFilepath);
string unique_user_id = textBox5.Text.Trim();
string secret_code = textBox1.Text.Trim();
// set the result of the Replace method on the string.
actionFileContent = ActionFileContent.Replace("UNIQUE_USER_ID", unique_user_id)
.Replace("SECRET_CODE", secret_code);
File.WriteAllText(Tmp_actionFilepath, actionFileContent);

Categories

Resources