I'm working on a small app which should read a file (ANSI 835) and replace data at certain positions with generic data. Basically I'm trying to scrub a person's first and last name from the file.
The line I'm searching for that contains the name looks like this:
NM1*QC*1*Doe*John*R***MI*010088307 01~
My code looks like this:
string[] input_file = (string[])(e.Data.GetData(DataFormats.FileDrop));
string output_file = #"c:\scrubbed.txt";
foreach (string file in input_file)
{
string[] lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (line.StartsWith("NM1*QC"))
{
line.Split('*')[1] = "Lastname";
line.Split('*')[2] = "Firstname";
}
}
File.WriteAllLines(output_file, lines);
}
The File.WriteAllLines works, but the data isn't being changed. I'm trying to get any line that starts with NM1*QC to look like this:
NM1*QC*1*Lastname*Firstname*R***MI*010088307 01~
There are many lines in the file that start with NM1*QC. What's the proper way to 'find and replace' and then create a new file in this situation?
As always, thanks for your time!
The calls to String.Split return variables that you neither capture, nor use, they do not change the underlying string. So your code equates to this:
if (line.StartsWith("NM1*QC"))
{
string[] split1 = line.Split('*')[1] = "Lastname";
string[] split2 = line.Split('*')[2] = "Firstname";
}
You would need to take the results of split1 and split2 and use those to recreate your string. Here is how I would re-write your code:
string[] input_file = (string[])(e.Data.GetData(DataFormats.FileDrop));
string output_file = #"c:\scrubbed.txt";
foreach (string file in input_file)
{
string[] lines = File.ReadAllLines(file);
for (int i=0; i < lines.length; i++)
{
string line = lines[i];
if (line.StartsWith("NM1*QC"))
{
string[] values = line.Split('*');
values[1] = "Lastname";
values[2] = "Firstname";
lines[i] = String.Join("*", values);
}
}
File.WriteAllLines(output_file, lines);
}
Notice I am recombining the individual values using the String.Join method, and inserting the new string back into the array of lines. That will then get written out as you expect.
Here you are creating a temporary array:
line.Split('*')
And you are changing its contents:
line.Split('*')[1] = "Lastname";
After the line has been executed the reference to this temporary array is lost and along with it go your changes.
In order to persist the changes you need to write directly to lines:
for (var i = 0; i < lines.Length; ++i)
{
var line = lines[i];
if (!line.StartsWith("NM1*QC"))
{
continue;
}
var parts = line.Split('*');
parts[3] = "Lastname";
parts[4] = "Firstname";
lines[i] = string.Join("*", parts);
}
Related
How can I find a line in C# and overwrite it (.sii file)?
string result = string.Empty;
var lines = File.ReadAllLines(Path);
foreach (var line in lines)
{
if (line.Contains("my_truck_placement: ("))
{
var text = line.Replace("my_truck_placement: ", "");
result = text.Trim();
File.WriteAllText(Path, result);
}
}
The main problem of yours is that you are trying to write to file too early, before you finish analyzing content of the file.
// use implicit types wherever possible
// Good to explicitly initiate with string.Empty :)
var result = string.Empty;
var lines = File.ReadAllLines(Path);
// I prefer here for each loop, as we are oging ot modify content of
// collection being iterated over.
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (line.Contains("my_truck_placement: ("))
{
lines[i] = line.Replace("my_truck_placement: ", "");
}
}
// Here, after all manipulations, you are able to write to file.
File.WriteAllLines(Path, lines);
You could simplify even further, for example loop body:
lines[i] = lines[i].Replace("my_truck_placement: (", "(");
If you are sure the phrase will only happen at the beginning of the line.
You could even limit yourself to such code
File.WriteAllLines(
Path,
File.ReadAllLines(Path)
.Select(x => x.Replace("my_truck_placement: (", "("))
.ToArray());
I have a text file containing the following lines:
<TestInfo."Content">
{
<Label> "Content"
<Visible> "true"
"This is the text I want to get"
}
<TestInfo."Content2">
{
<Label> "Content2"
<Visible> "true"
"I don't want e.g. this"
}
I want to extract This is the text I want to get.
I tried e.g. the following:
string tmp = File.ReadAllText(textfile);
string result = Regex.Match(tmp, #"<Label> ""Content"" \n\s+ <Visible> ""true"" \n\s+ ""(.+?)""", RegexOptions.Singleline).Groups[1].Value;
However, in this case I get only the first word.
So, my output is: This
And I have no idea why...
I would appreciate any help. Thanks!
If you want the entire line after the line that starts with <Visible>, you'd better read the file line by line instead of using File.ReadAllText and a regular expression:
string result;
using (StreamReader sr = new StreamReader(textfile))
{
while (sr.Peek() >= 0)
{
string line = sr.ReadLine();
if (line.StartsWith("<Visible>"))
{
result = sr.ReadLine();
break;
}
}
}
Try this:
var tmp = File.ReadAllText("TextFile1.txt");
var result = Regex.Match(tmp, "This is the text I want to get", RegexOptions.Multiline);
if (result.Groups.Count> 0)
for (int i = 0; i < result.Groups.Count; i++)
Console.WriteLine(result.Groups[i].Value);
else
Console.WriteLine("string not found.");
Regards,
//jafc
You could change your regex this way:
var result = Regex.Match(tmp, #"<Visible> ""true""\s*""([\S ]+)""", RegexOptions.Singleline).Groups[1].Value;
If you want to get all the matches, not only the first one, you could use Regex.Matches
Thanks a lot for your input! This helped me to find a final solution:
First, I extracted only a small part containing the string I want to extract to avoid ambiguities:
string[] tmp = File.ReadAllLines(textfile);
List<string> Content = new List<string>();
bool dumpA = false;
Regex regBEGIN = new Regex(#"<TestInfo\.""Content"">");
Regex regEND = new Regex(#"<TestInfo\.""Content2"">");
foreach (string line in tmp)
{
if (dumpA)
Content.Add(line.Trim());
if (regBEGIN.IsMatch(line))
dumpA = true;
if (regEND.IsMatch(line)) break;
}
Then I can extract the (now only once existing) line starting with '"':
string result = "";
foreach (string line in Content)
{
if (line.StartsWith("\""))
{
result = line;
result = result.Replace("\"", "");
result = result.Trim();
}
}
Hey I am currently stuck. I have the following code that takes a line from a file, based on specific string and returns it, then it can be edited, and applied back to a textbox that contains the file content into the line that the string was initially taken from.
private void citationChange()
{
List<string> matchedList = new List<string>();
string[] linesArr = File.ReadAllLines(fileName);
//find matches
for (int a = 0; a < linesArr.Length; a++)
{
string s = linesArr[a];
if (s.Contains(citation))
{
matchedList.Add(linesArr[a]); //matched
lineBeingEdited = a;
break; //breaks the loop when a match is found
}
}
//output
foreach (string s in matchedList)
{
string citationLine = s;
string[] lineData = citationLine.Split(',');
editModuleComboBox.Text = lineData[1];
selectedModuleLabel.Text = lineData[2];
moduleTitleTextBox.Text = lineData[3];
creditsTextBox.Text = lineData[4];
semesterTextBox.Text = lineData[5];
examWeightingTextBox.Text = lineData[6];
examMarkTextBox.Text = lineData[7];
testWeightingTextBox.Text = lineData[8];
testMarkTextBox.Text = lineData[9];
courseworkWeightingTextBox.Text = lineData[10];
courseworkMarkTexbox.Text = lineData[11];
}
}
How can I recreate/change this code but for it to read a textbox instead of a file?
Thanks
Change this:
string[] linesArr = File.ReadAllLines(fileName);
to:
string[] linesArr = theTextBox.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
When reading your file File.ReadAllLines basically splits the entire text by \r\n. So you could do this with your text from the textbox:
exchange this line:
string[] linesArr = File.ReadAllLines(fileName);
to this:
string[] linesArr = YourTextBox.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
or this:
string[] linesArr = YourTextBox.Text.Split(new char[] {'\r', '\n'});
I want to write a string next to a line, randomly could be any line, also I want to know how to delete a line from it, here is how my StreamReader works:
using (StreamReader sb = new StreamReader("admin.txt"))
{
string[] ffoo = File.ReadAllLines("admin.txt");
string[] ppoof = ffoo[0].Split(';');
string line;
while ((line = sb.ReadLine()) != null)
{
if (line.StartsWith("#" + Server.Name.ToLower() + ": "))
{
string[] punch = line.Split(';');
if (!punch.Contains(Channel.Name.ToLower()))
{
StringBuilder str = new StringBuilder("admin.txt");
str.Append(Channel.Name.ToLower() + ";");
return;
}
}
}
Here is how the list is made:
#main: alien;nobody;somebody;
#devs: headdev;wae;
It reads it fine just it can't write something next to main channel, I mean I can only write a line or a string next to end of it which is on dev, and I want to write something on main, also I have some problems on how to delete an admin from main or dev. also this file would be oversize, maybe includes 500 lines at all after we use it, so please if you can give a solution for big files, thanks!
When calling StringBuilder.Append it appends to the end of the string.
When calling the StringBuilder(string) constructor it will append to the string passed as parameter for the constructor.
In this case you are passing "Admin.txt" as a string, but you really want to pass the content of Admin.txt, so you need to read the content of it.
This should do the trick:
string[] lines = File.ReadAllLines("admin.txt");
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith(string.Format("#{0}: ", Server.Name.ToLower()))
{
if (!lines[i].Split(';').Contains(Channel.Name.ToLower()))
lines[i] += ";" + Channel.Name.ToLower();
}
}
File.WriteAllLines("admin.txt", lines);
I'm sorry if I misunderstood what you wanted to do though.
I'm making this application for fun but i have a problem
I want this string/file to be read in seperate lines.
this the file(not the whole file):
1ChampSelectPack.Ahri.mp31ChampSelectPack.Akali.mp31ChampSelectPack.Alistar.mp31ChampSelectPack.Amumu.mp31ChampSelectPack.Anivia.mp31ChampSelectPack.Annie.mp31ChampSelectPack.Ashe.mp31ChampSelectPack.Blitzcrank.mp31ChampSelectPack.Brand.mp31ChampSelectPack.Caitlyn.mp3
and this is what i got so far:
List<SoundPath> paths = new List<SoundPath>();
StreamReader reader = File.OpenText("C:/Users/Esat/Documents/Visual Studio 2010/Projects/WikiLoL/WikiLoL/lolSoundBoard/1ChampSelectPack/files.txt");
while (!reader.EndOfStream)
{
SoundPath path = new SoundPath();
path.Path = reader.ReadLine();
paths.Add(path);
}
reader.Close();
return paths;
Not sure if that is what you want:
"YourString".Split(new string[] {"mp3"}, StringSplitOptions.None)
You would have to append the "mp3" on each line afterwards.
You can do it using splitting on .mp3 and adding .mp3 in each element of resultant array.
string text = File.ReadAllText("C:/Users/Esat/Documents/Visual Studio 2010/Projects/WikiLoL/WikiLoL/lolSoundBoard/1ChampSelectPack/files.txt");
string[] lines = text.Split(new string[] { ".mp3" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < lines.Length; i++)
lines[i] = lines[i] + ".mp3";