Both the below cases are not working. I want to extract from a text file a certain part that I can choose by specifying the start of the line and end.
case looks like this:
using (StreamReader reader = new StreamReader("C:/Users/david/Desktop/20180820.log",Encoding.Default))
{
Console.WriteLine("From:");
string a = (Console.ReadLine());
Console.WriteLine(" To:");
string b = (Console.ReadLine());
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(a) && (line.EndsWith(b)))
{
Console.WriteLine(line);
}
}
}
case with regex
string line;
while ((line = reader.ReadLine()) != null)
{
string regex12 = a.ToString() + b.ToString();
Match m = Regex.Match(line,regex12);
string s = Regex.Match(line, regex12).Groups[0].Value;
Console.WriteLine(s);
if (m.Success)
{
string n = m.Groups[0].Value;
Console.WriteLine(n);
}
}
If anyone can solve my problem, I will be very thankful.
Update Based on Comments
From the comments, it looks like you are attempting to parse a specifically formatted file, and would better benefit with a non-generic solution. Also, it looks like the text is split across multiple lines, rather than single line as you had shared in comments.
[00:09:08.870] text...
[00:09:08.886] text...
[00:09:08.886] text...
[00:09:10.448] text...
[00:09:10.464] text...
[00:09:10.526] text...
[00:09:11.886] text...
[00:09:11.901] text...
[00:09:11.980] text...
[00:09:12.026] text...
In this case, you could use the following.
var reader = File.OpenText(filePAth);
var startLineDetected = false;
var startWord = "00:09:08.870";
var endWord = "00:09:12.026";
var strBuilder = new StringBuilder();
while(!reader.EndOfStream)
{
var newLine = reader.ReadLine();
if(newLine.Contains($"[{startWord}") && !startLineDetected)
{
startLineDetected = true;
}
if(newLine.Contains($"[{endWord}") && startLineDetected)
{
strBuilder.AppendLine(newLine);
break;
}
if(startLineDetected)
{
strBuilder.AppendLine(newLine);
}
}
var resultData = strBuilder.ToString();
Original Answer based on OP
You could do the following.
var reader = File.OpenText(filePAth);
var startLineDetected = false;
var startWord = // startWord;
var endWord = // endWord;
var strBuilder = new StringBuilder();
while(!reader.EndOfStream)
{
var newLine = reader.ReadLine();
if(newLine.Contains(startWord) && !startLineDetected)
{
startLineDetected = true;
newLine = newLine.Substring(newLine.IndexOf(startWord));
}
if(newLine.Contains(endWord) && startLineDetected)
{
newLine = newLine.Substring(0,newLine.IndexOf(endWord) + endWord.Length);
strBuilder.Append(newLine);
break;
}
if(startLineDetected)
{
strBuilder.Append(newLine);
}
}
var resultData = strBuilder.ToString();
I split them to get first letter to be upper case now I'm having problem merging them and the first letters are still upper cased. Also my data is from a database
private void button1_Click(object sender, EventArgs e)
{
//input = input.Replace("_", "");
string input;
input = table_menu.Text;
string[] words = input.Split('_');
foreach (string word in words)
{
string nword = word.First().ToString().ToUpper() + String.Join("", word.Skip(1));
string merge = String.Join("", nword);
MessageBox.Show(merge);
}
label1.Text = input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
Console.WriteLine(label1.Text);
}
Current Ouput: tablepatient
I want a out to be like this:
TablePatient
The concept of capitalization is culture-specific - capitalization in one culture may not be the same as capitalization in another. If you are serializing your strings to XML for persistent storage, you probably want to use the invariant culture; if you are showing them to a user, then the local culture (or maybe the local UI culture) is appropriate.
That being said, the following probably do the job:
public static string UnderscoreToTitleCase(string input)
{
return UnderscoreToTitleCase(input, System.Globalization.CultureInfo.CurrentCulture);
}
public static string UnderscoreToTitleCaseInvariant(string input)
{
return UnderscoreToTitleCase(input, System.Globalization.CultureInfo.InvariantCulture);
}
public static string UnderscoreToTitleCase(string input, CultureInfo cultureInfo)
{
string[] words = input.Split('_');
StringBuilder sb = new StringBuilder();
foreach (string word in words)
sb.Append(cultureInfo.TextInfo.ToTitleCase(word));
return (sb.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
string input;
input = table_menu.Text;
string[] words = input.Split('_');
StringBuilder sb = new StringBuilder();
foreach (string word in words)
{
string nword = word.First().ToString().ToUpper() + String.Join("", word.Skip(1));
string merge = String.Join("", nword);
MessageBox.Show(merge);
sb.Append(nword);
}
label1.Text = sb.ToString();
Console.WriteLine(label1.Text);
}
This works:
var input = "table_patient";
var output = String.Join("",
input
.Split('_')
.Where(x => !String.IsNullOrEmpty(x))
.Select(x => new string(
x
.Take(1)
.Select(c => char.ToUpperInvariant(c))
.Concat(x.Skip(1))
.ToArray())));
//output == "TablePatient"
This also works:
var output = System
.Globalization
.CultureInfo
.CurrentCulture
.TextInfo
.ToTitleCase(input)
.Replace("_", "");
I have two foreach loops, each of which loops through a text file, and gets the value of all of the values of the first two columns only (there are more than two columns in the text file, delimited by "|") and puts it in a string. I would like to compare the result of these foreach loops (the values that are output by the Response.Write statements) to see if the strings are equivalent or not. Any thoughts/suggestions appreciated.
protected void Page_Load(object sender, EventArgs e)
{
string textFile1 = #"C:\Test\Test1.txt";
string textFile2 = #"C:\Test\Test2.txt";
string[] textFile1Lines = System.IO.File.ReadAllLines(textFile1);
string[] textFile2Lines = System.IO.File.ReadAllLines(textFile2);
char[] delimiterChars = { '|' };
foreach (string line in textFile1Lines)
{
string[] words = line.Split(delimiterChars);
string column1And2 = words[0] + words[1];
Response.Write(column1And2);
}
foreach (string line in textFile2Lines)
{
string[] words = line.Split(delimiterChars);
string column1And2 = words[0] + words[1];
Response.Write(column1And2);
}
}
One way to compare the outputs would be storing the strings as you go, and then compare the results using SequenceEqual. Since the two loops are identical, consider making a static method out of them:
// Make the extraction its own method
private static IEnumerable<string> ExtractFirstTwoColumns(string fileName) {
return System.IO.File.ReadLines(fileName).Select(
line => {
string[] words = line.Split(delimiterChars);
return words[0] + words[1];
}
);
}
protected void Page_Load(object sender, EventArgs e)
// Use extraction to do both comparisons and to write
var extracted1 = ExtractFirstTwoColumns(#"C:\Test\Test1.txt").ToList();
var extracted2 = ExtractFirstTwoColumns(#"C:\Test\Test2.txt").ToList();
// Write the content to the response
foreach (var s in extracted1) {
Response.Write(s);
}
foreach (var s in extracted2) {
Response.Write(s);
}
// Do the comparison
if (extracted1.SequenceEqual(extracted2)) {
Console.Error.WriteLine("First two columns are different.");
}
}
I would simply compare in the same loop, using for instead of foreach:
protected void Page_Load(object sender, EventArgs e)
{
string textFile1 = #"C:\Test\Test1.txt";
string textFile2 = #"C:\Test\Test2.txt";
string[] textFile1Lines = System.IO.File.ReadAllLines(textFile1);
string[] textFile2Lines = System.IO.File.ReadAllLines(textFile2);
char[] delimiterChars = { '|' };
if (textFile1Lines.Count != textFile2Lines.Count)
{
// Do something since the line counts don't match
}
else
{
foreach (int i = 0; i < textFile1Lines.Count; i++)
{
string[] words1 = textFile1Lines[i].Split(delimiterChars);
string compareValue1 = words1[0] + words1[1];
string[] words2 = textFile2Lines[i].Split(delimiterChars);
string compareValue2 = words2[0] + words2[1];
if (!string.Equals(compareValue1, compareValue2))
{
// Do something
break; // Exit the loop since you found a difference
}
}
}
}
I have different string that starts and ends with { } like so {somestring}. I want to remove the delimiters from the string so that it shows somestring only. I can't do anything that counts the letters because I don't always know the length of the string.
Maybe this will help. Here is the code, somewhere here I want to delete the delimiters.
private static MvcHtmlString RenderDropDownList(FieldModel model)
{
ISerializer serializer = new SerializeJSon();
var value = "";
var tb1 = new TagBuilder("select");
tb1.MergeAttribute("id", model.QuestionId);
tb1.MergeAttribute("name", model.QuestionId);
tb1.MergeAttributes(GetHtmlAttributes(model.HtmlAttributes));
tb1.AddCssClass("form-field");
var sb = new StringBuilder();
MatchCollection matches = RegexHelper.GetBetweenDelimiter(model.FieldValues, "{", "}");
foreach (Match match in matches)
{
var o = match; //Solution var o = match.toString();
var tb2 = new TagBuilder("option");
//Solution string newString = o.trim(new [] { "{","}"});
tb2.SetInnerText(o.ToString()); //Solution tb2.SetInnerText(newString);
sb.Append(tb2.ToString(TagRenderMode.Normal) + "\n");
}
tb1.InnerHtml = sb.ToString();
return new MvcHtmlString(tb1.ToString(TagRenderMode.Normal));
}
string newString = originalString.Trim(new[] {'{', '}'});
Can you use Replace
string somestring = somestring.Replace("{","").Replace("}","");
Alternatively, you can use StartsWith and EndsWith which will only remove from the beginning and the end of the string, for example:
string foo = "{something}";
if (foo.StartsWith("{"))
{
foo = foo.Remove(0, 1);
}
if (foo.EndsWith("}"))
{
foo = foo.Remove(foo.Length-1, 1);
}
You could use replace e.g.
string someString = "{somestring}";
string someOtherString = someString.Replace("{","").Replace("}","");
I have a dynamic String value which may contain values like this
"Apple ,Banana, , , , Mango ,Strawberry , "
I would like to filter this string like
"Apple,Banana,Mango,Strawberry".
I have tried with the following code and it works.
Is there any better approach to achieve the same in C#(.NET 2.0)?
/// <summary>
/// Convert "Comma Separated String" to "Comma Separated String"
/// </summary>
/// <param name="strWithComma">String having values separated by comma</param>
/// <returns>String separated with comma</returns>
private String CommaSeparatedString(String strWithComma)
{
String rtn = String.Empty;
List<String> newList= new List<string>();
if (String.IsNullOrEmpty(strWithComma))
{
return rtn;
}
String[] strArray = strWithComma.Split(",".ToCharArray());
if (strArray == null || strArray.Length == 0)
{
return rtn;
}
String tmpStr = String.Empty;
String separator=String.Empty;
foreach (String s in strArray)
{
if (!String.IsNullOrEmpty(s))
{
tmpStr =s.Replace(Environment.NewLine, String.Empty);
tmpStr = tmpStr.Trim();
if (!String.IsNullOrEmpty(tmpStr))
{
newList.Add(tmpStr);
}
}
}
if (newList != null && newList.Count > 0)
{
rtn = String.Join(",", newList.ToArray());
}
return rtn;
}
you can also use Regex:
string str = #"Apple ,,Banana, , , , Mango ,Strawberry , ";
string result = Regex.Replace(str, #"(\s*,\s*)+", ",").TrimEnd(',');
I believe the following should do the trick on any .NET version:
string[] TrimAll( string[] input )
{
var result = new List<string>();
foreach( var s in input )
result.Add( s.Trim() );
}
return result.ToArray();
}
var delimiters = new [] { ",", "\t", Environment.NewLine };
string result = string.Join(",", TrimAll( input.Split( delimiters, StringSplitOptions.RemoveEmptyEntries ) ) );
Edit: updated to deal with white-space, tabs and newline.
Assuming that your items do not contain spaces:
private String CommaSeparatedString(String strWithComma)
{
string[] tokens = strWithComma
.Replace(" ", "")
.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
return string.Join(",", tokens);
}
Now I'm not sure if C# 2.0 accepts the new char[] {','} syntax. If not, you can define the array somewhere else (as a class private member, for example).
Here's a one-liner:
var outputString = string.Join(",", inputString.Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
Regex regex = new Regex(#"\w(?:(?!,| ).)*");
var items = regex.Matches("Apple ,Banana, , , , Mango ,Strawberry , ").Cast<Match>().Select(m => m.Value);
.NET 2.0 Version
List<string> newList = new List<string>();
Regex regex = new Regex(#"\w(?:(?!,| ).)*");
string str = "Apple ,Banana, , , , Mango ,Strawberry , ";
MatchCollection matches = regex.Matches(str);
foreach (Match match in matches)
{
newList.Add(match.Value);
}
var result = Regex.Replace(strWithComma, ",+", ",").TimEnd(',');
result = Regex.Replace(result, "\s+", string.Empty);
With no regular expressions, no splits and joins, trims, etc, O(n) time. StringBuilder is a very good class to work with strings.
EDIT
If the string it doesn't end with a letter it will add a comma. So an extra TrimEnd(',') is added
string strWithComma = ",Apple ,Banana, , , , Mango ,Strawberry , \n John,";
var sb = new StringBuilder();
var addComma = false;
foreach (var c in strWithComma )
{
if (Char.IsLetter(c)) // you might want to allow the dash also: example Anne-Marie
{
addComma = true;
sb.Append(c);
}
else
{
if (addComma)
{
addComma = false;
sb.Append(',');
}
}
}
string rtn = sb.ToString().TrimEnd(',');
Warning this method will only apply for C# 3.0 or higher. Sorry guys didnt read the question well enough
This will work but it can be done much easier like:
string input = "apple,banana,, \n,test\n, ,juice";
var parts = from part in input.Split(',')
let trimmedPart = part.Replace("\n", "")
where !string.IsNullOrWhiteSpace(trimmedPart)
select trimmedPart;
string result = string.Join(",", parts);