I have the following code in a text file:
static const char* g_FffectNames[EFFECT_COUNT] = {
"Fade In and Fade Out",
"Halloween Eyes",
"Rainbow Cycles"
};
I can use g_FffectNames[EFFECT_COUNT] as a starting point to search in this big text file. But I need to get the things within quotes (e.g Halloween Eyes or Rainbow Cycles).
What is the best way to get those text in C#? I would also have to assume that there are more code on top of this file (before the static const) and also toward the bottom (after the }; ) and that spacing between characters such as = { or }; is optional to the user.
Should I compress all of these lines into one string and start the search or should I use some sort of regex matching to make this easier?
You can use a regular expressions to parse input file:
var input = /* file content */;
var regex = new Regex("^\\s*\"(?<row>[^\"]+)\\s*\"", RegexOptions.Multiline);
var values = regex.Matches(input)
.Cast<Match>()
.Select(m => m.Groups["row"]).ToArray();
I got it working based on this post:
c# search string in txt file
public string readText()
{
string test = string.Empty;
var mytext = File.ReadLines("C:\\temp\\test_search.txt")
.SkipWhile(line => !line.Contains("g_FffectNames[EFFECT_COUNT]"))
.Skip(1)
.TakeWhile(line => !line.Contains("};"));
foreach (var line in mytext)
{
test += line;
}
return test;
}
Related
Can anyone tell me why this is not working:
string txt = "+0°1,0'";
string degree = txt.TrimEnd('°');
I am trying to separate the degrees on this string, but after this, what remains on degree is the same content of txt.
I am using C# in Visual Studio.
string.TrimEnd remove char at the end. In your example, '°' isn't at the end.
For example :
string txt = "+0°°°°";
string degree = txt.TrimEnd('°');
// degree => "+0"
If you want remove '°' and all next characters, you can :
string txt = "+0°1,0'";
string degree = txt.Remove(txt.IndexOf('°'));
// degree => "+0"
string txt = "+0°1,0'";
if(txt.IndexOf('°') > 0) // Checking if character '°' exist in the string
{
string withoutdegree = txt.Remove(txt.IndexOf('°'),1);
}
Another safe way of handling the same is using the String.Split method. You will not have to bother to verify the presence of the character in this case.
string txt = "+0°1,0'";
var str = txt.Split('°')[0]; // "+0"
string txt = "+01,0'";
var str = txt.Split('°')[0]; // "+01,0'"
You can use this to remove all the '°' symbols present in your string using String.Replace
string txt = "+0°1,0'°°";
var text = txt.Replace(#"°", ""); // +01,0'
Edit: Added a safe way to handle the OP's exact query.
Fast way to replace text in text file.
From this: somename#somedomain.com:hello_world
To This: somename:hello_world
It needs to be FAST and support multiple lines of text file.
I tried spiting the string into three parts but it seems slow. Example in the code below.
<pre><code>
public static void Conversion()
{
List<string> list = File.ReadAllLines("ETU/Tut.txt").ToList();
Console.WriteLine("Please wait, converting in progress !");
foreach (string combination in list)
{
if (combination.Contains("#"))
{
write: try
{
using (StreamWriter sw = new
StreamWriter("ETU/UPCombination.txt", true))
{
sw.WriteLine(combination.Split('#', ':')[0] + ":"
+ combination.Split('#', ':')[2]);
}
}
catch
{
goto write;
}
}
else
{
Console.WriteLine("At least one line doesn't contain #");
}
}
}</code></pre>
So a fast way to convert every line in text file from
somename#somedomain.com:hello_world
To: somename:hello_world
then save it different text file.
!Remember the domain bit always changes!
Most likely not the fastest, but it is pretty fast with an expression similar to,
#[^:]+
and replace that with an empty string.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = #"#[^:]+";
string substitution = #"";
string input = #"somename#somedomain.com:hello_world1
somename#some_other_domain.com:hello_world2";
RegexOptions options = RegexOptions.Multiline;
Regex regex = new Regex(pattern, options);
string result = regex.Replace(input, substitution);
}
}
If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
RegEx Circuit
jex.im visualizes regular expressions:
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to covert tab separated file to CSV file
i have a tab delimited text file which i have to convert into CSV file all this must be done through C# code. My txt file is very large about(1.5 GB), hence i want to convert it in a quick time. please help me.
If your input tab delimited text file does not have any commas are part of the data, then it is a very straightforward find and replace similar to the other answers here:
var lines = File.ReadAllLines(path);
var csv= lines.Select(row => string.Join(",", row.Split('\t')));
File.WriteAllLines(path, csv);
But if your data has commas, doing this is going to break your columns as you now have extra commas that are not supposed to be delimiters, but will be interpreted as such. How to handle it depends greatly on what you application you will be using to read the CSV.
A Microsoft Excel compatible CSV is going to have double quotes around fields with commas to make sure they are interpreted as data and not a delimiter. This also means that fields that contain double quotes as data will need special treatment.
I would recommend a similar approach with an extension method.
var input = File.ReadAllLines(path);
var lines = input.Select(row => row.Split('\t'));
lines = lines.Select(row => row.Select(field => field.EscapeCsvField(',', '"')).ToArray());
var csv = lines.Select(row => string.Join(",", row));
File.WriteAllLines(path, csv.ToArray());
And here's the EscapeCsvField extension method:
static class Extension
{
public static String EscapeCsvField(this String source, Char delimiter, Char escapeChar)
{
if (source.Contains(delimiter) || source.Contains(escapeChar))
return String.Format("{0}{1}{0}", escapeChar, source);
return source;
}
}
Also, if the file is large, it might be best to not read the entire file into memory. In that case, I would suggest writing the CSV output to a different file and then you could use StreamReader and StreamWriter to only work with it 1 line at a time.
var tabPath = path;
var csvPath = Path.Combine(
Path.GetDirectoryName(path),
String.Format("{0}.{1}", Path.GetFileNameWithoutExtension(path), "csv"));
using (var sr = new StreamReader(tabPath))
using (var sw = new StreamWriter(csvPath, false))
{
while (!sr.EndOfStream)
{
var line = sr.ReadLine().Split('\t').Select(field => field.EscapeCsvField(',', '"')).ToArray();
var csv = String.Join(",", line);
sw.WriteLine(csv);
}
}
File.Delete(tabPath);
var csv = File.ReadAllLines("Path").Select(line => line.Replace("\t", ","));
You could simply call
public void ConvertToCSV(string strPath, string strOutput)
{
File.WriteAllLines(strOutput, File.ReadAllLines("Path").Select(line => line.Replace("\t", ",")));
}
There is a lot of content already on SO for handling .CSV files, please search first or trying something.
If the format of your file is strict, you could use string.Split and string.Join:
var lines = File.ReadAllLines(path);
var newLines = lines.Select(l => string.Join(",", l.Split('\t')));
File.WriteAllLines(path, newLines);
I have a .txt file with a list of 174 different strings. Each string has an unique identifier.
For example:
123|this data is variable|
456|this data is variable|
789|so is this|
etc..
I wish to write a programe in C# that will read the .txt file and display only one of the 174 strings if I specify the ID of the string I want. This is because in the file I have all the data is variable so only the ID can be used to pull the string. So instead of ending up with the example about I get just one line.
eg just
123|this data is variable|
I seem to be able to write a programe that will pull just the ID from the .txt file and not the entire string or a program that mearly reads the whole file and displays it. But am yet to wirte on that does exactly what I need. HELP!
Well the actual string i get out from the txt file has no '|' they were just in the example. An example of the real string would be: 0111111(0010101) where the data in the brackets is variable. The brackets dont exsist in the real string either.
namespace String_reader
{
class Program
{
static void Main(string[] args)
{
String filepath = #"C:\my file name here";
string line;
if(File.Exists(filepath))
{
StreamReader file = null;
try
{
file = new StreamReader(filepath);
while ((line = file.ReadLine()) !=null)
{
string regMatch = "ID number here"; //this is where it all falls apart.
Regex.IsMatch (line, regMatch);
Console.WriteLine (line);// When program is run it just displays the whole .txt file
}
}
}
finally{
if (file !=null)
file.Close();
}
}
Console.ReadLine();
}
}
}
Use a Regex. Something along the lines of Regex.Match("|"+inputString+"|",#"\|[ ]*\d+\|(.+?)\|").Groups[1].Value
Oh, I almost forgot; you'll need to substitute the d+ for the actual index you want. Right now, that'll just get you the first one.
The "|" before and after the input string makes sure both the index and the value are enclosed in a | for all elements, including the first and last. There's ways of doing a Regex without it, but IMHO they just make your regex more complicated, and less readable.
Assuming you have path and id.
Console.WriteLine(File.ReadAllLines(path).Where(l => l.StartsWith(id + "|")).FirstOrDefault());
Use ReadLines to get a string array of lines then string split on the |
You could use Regex.Split method
FileInfo info = new FileInfo("filename.txt");
String[] lines = info.OpenText().ReadToEnd().Split(' ');
foreach(String line in lines)
{
int id = Convert.ToInt32(line.Split('|')[0]);
string text = Convert.ToInt32(line.Split('|')[1]);
}
Read the data into a string
Split the string on "|"
Read the items 2 by 2: key:value,key:value,...
Add them to a dictionary
Now you can easily find your string with dictionary[key].
first load the hole file to a string.
then try this:
string s = "123|this data is variable| 456|this data is also variable| 789|so is this|";
int index = s.IndexOf("123", 0);
string temp = s.Substring(index,s.Length-index);
string[] splitStr = temp.Split('|');
Console.WriteLine(splitStr[1]);
hope this is what you are looking for.
private static IEnumerable<string> ReadLines(string fspec)
{
using (var reader = new StreamReader(new FileStream(fspec, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
}
var dict = ReadLines("input.txt")
.Select(s =>
{
var split = s.Split("|".ToArray(), 2);
return new {Id = Int32.Parse(split[0]), Text = split[1]};
})
.ToDictionary(kv => kv.Id, kv => kv.Text);
Please note that with .NET 4.0 you don't need the ReadLines function, because there is ReadLines
You can now work with that as any dictionary:
Console.WriteLine(dict[12]);
Console.WriteLine(dict[999]);
No error handling here, please add your own
You can use Split method to divide the entire text into parts sepparated by '|'. Then all even elements will correspond to numbers odd elements - to strings.
StreamReader sr = new StreamReader(filename);
string text = sr.ReadToEnd();
string[] data = text.Split('|');
Then convert certain data elements to numbers and strings, i.e. int[] IDs and string[] Strs. Find the index of the given ID with idx = Array.FindIndex(IDs, ID.Equals) and the corresponding string will be Strs[idx]
List <int> IDs;
List <string> Strs;
for (int i = 0; i < data.Length - 1; i += 2)
{
IDs.Add(int.Parse(data[i]));
Strs.Add(data[i + 1]);
}
idx = Array.FindIndex(IDs, ID.Equals); // we get ID from input
answer = Strs[idx];
I have an .EDF (text) file. The file's contents are as follows:
ConfigFile.Sample, Software v0.32, CP Version 0.32
[123_Float][2]
[127_Number][0]
[039_Code][70]
I wnat to read these items and parse them like this:
123_Float - 2
127_Number - 0
039_Code - 70
How can I do this using C#?
Well, you might start with the File.ReadAllLines() method. Then, iterate through the lines in that file, checking to see if they match a pattern. If they do, extract the necessary text and do whatever you want with it.
Here's an example that assumes you want lines in the format [(field 1)][(field 2)]:
// Or wherever your file is located
string path = #"C:\MyFile.edf";
// Pattern to check each line
Regex pattern = new Regex(#"\[([^\]]*?)\]");
// Read in lines
string[] lines = File.ReadAllLines(path);
// Iterate through lines
foreach (string line in lines)
{
// Check if line matches your format here
var matches = pattern.Matches(line);
if (matches.Count == 2)
{
string value1 = matches[0].Groups[1].Value;
string value2 = matches[1].Groups[1].Value;
Console.WriteLine(string.Format("{0} - {1}", value1, value2));
}
}
This outputs them to the console window, but you could obviously do whatever you want with value1 and value2 (write them to another file, store them in a data structure, etc).
Also, please note that regular expressions are not my strong point -- there's probably a much more elegant way to check if a line matches your pattern :)
If you want more info, check out MSDN's article on reading data from a text file as a starting point.
Let us assume your file really is as simple as you describe it. Then you could drop the first line and parse the data lines like this:
foreach (string line in File.ReadAllLines(#"C:\MyFile.edf").Skip(1))
{
var parts = line.Split("][");
var value1 = parts[0].Replace("[", "");
var value2 = parts[1].Replace("]", "");
Console.WriteLine(string.Format("{0} - {1}", value1, value2));
}
Another variation.
var lines = File.ReadAllLines(file)
.Skip(1)
.Select(x => x.Split(new[] { '[', ']' },
StringSplitOptions.RemoveEmptyEntries));
foreach(var pair in lines)
{
Console.WriteLine(pair.First()+" - "+pair.Last());
}