Currently I am building an agenda with extra options.
for testing purposes I store the data in a simple .txt file
(after that it will be connected to the agenda of a virtual assistant.)
To change or delete text from this .txt file I have a problem.
Although the part of the content that needs to be replaced and the search string are exactly the same it doesn't replace the text in content.
code:
Change method
public override void Change(List<object> oldData, List<object> newData)
{
int index = -1;
for (int i = 0; i < agenda.Count; i++)
{
if(agenda[i].GetType() == "Task")
{
Task t = (Task)agenda[i];
if(t.remarks == oldData[0].ToString() && t.datetime == (DateTime)oldData[1] && t.reminders == oldData[2])
{
index = i;
break;
}
}
}
string search = "Task\r\nTo do: " + oldData[0].ToString() + "\r\nDateTime: " + (DateTime)oldData[1] + "\r\n";
reminders = (Dictionary<DateTime, bool>) oldData[2];
if(reminders.Count != 0)
{
search += "Reminders\r\n";
foreach (KeyValuePair<DateTime, bool> rem in reminders)
{
if (rem.Value)
search += "speak " + rem.Key + "\r\n";
else
search += rem.Key + "\r\n";
}
}
// get new data
string newRemarks = (string)newData[0];
DateTime newDateTime = (DateTime)newData[1];
Dictionary<DateTime, bool> newReminders = (Dictionary<DateTime, bool>)newData[2];
string replace = "Task\r\nTo do: " + newRemarks + "\r\nDateTime: " + newDateTime + "\r\n";
if(newReminders.Count != 0)
{
replace += "Reminders\r\n";
foreach (KeyValuePair<DateTime, bool> rem in newReminders)
{
if (rem.Value)
replace += "speak " + rem.Key + "\r\n";
else
replace += rem.Key + "\r\n";
}
}
Replace(search, replace);
if (index != -1)
{
remarks = newRemarks;
datetime = newDateTime;
reminders = newReminders;
agenda[index] = this;
}
}
replace method
private void Replace(string search, string replace)
{
StreamReader reader = new StreamReader(path);
string content = reader.ReadToEnd();
reader.Close();
content = Regex.Replace(content, search, replace);
content.Trim();
StreamWriter writer = new StreamWriter(path);
writer.Write(content);
writer.Close();
}
When running in debug I get the correct info:
content "-- agenda --\r\n\r\nTask\r\nTo do: test\r\nDateTime: 16-4-2012 15:00:00\r\nReminders:\r\nspeak 16-4-2012 13:00:00\r\n16-4-2012 13:30:00\r\n\r\nTask\r\nTo do: testing\r\nDateTime: 16-4-2012 9:00:00\r\nReminders:\r\nspeak 16-4-2012 8:00:00\r\n\r\nTask\r\nTo do: aaargh\r\nDateTime: 18-4-2012 12:00:00\r\nReminders:\r\n18-4-2012 11:00:00\r\n" string
search "Task\r\nTo do: aaargh\r\nDateTime: 18-4-2012 12:00:00\r\nReminders\r\n18-4-2012 11:00:00\r\n" string
replace "Task\r\nTo do: aaargh\r\nDateTime: 18-4-2012 13:00:00\r\nReminders\r\n18-4-2012 11:00:00\r\n" string
But it doesn't change the text. How do I make sure that the Regex.Replace finds the right piece of content?
PS. I did check several topics on this, but none of the solutions mentioned there work for me.
You missed a : right after Reminders. Just check it again :)
You could try using a StringBuilder to build up you want to write out to the file.
Just knocked up a quick example in a console app but this appears to work for me and I think it might be what you are looking for.
StringBuilder sb = new StringBuilder();
sb.Append("Tasks\r\n");
sb.Append("\r\n");
sb.Append("\tTask 1 details");
Console.WriteLine(sb.ToString());
StreamWriter writer = new StreamWriter("Tasks.txt");
writer.Write(sb.ToString());
writer.Close();
Related
I need to see if any phrase, such as "duckbilled platypus" appears in a string array.
In the case I'm testing, the phrase does exist in the string list, as shown here:
Yet, when I look for that phrase, as shown here:
...it fails to find it. I never get past the "if (found)" gauntlet in the code below.
Here is the code that I'm using to try to traverse through the contents of one doc to see if any phrase (two words or more) are found in both documents:
private void FindAndStorePhrasesFoundInBothDocs()
{
string[] doc1StrArray;
string[] doc2StrArray;
slPhrasesFoundInBothDocs = new List<string>();
slAllDoc1Words = new List<string>();
int iCountOfWordsInDoc1 = 0;
int iSearchStartIndex = 0;
int iSearchEndIndex = 1;
string sDoc1PhraseToSearchForInDoc2;
string sFoundPhrase;
bool found;
int iLastWordIndexReached = iSearchEndIndex;
try
{
doc1StrArray = File.ReadAllLines(sDoc1Path, Encoding.UTF8);
doc2StrArray = File.ReadAllLines(sDoc2Path, Encoding.UTF8);
foreach (string line in doc1StrArray)
{
string[] subLines = line.Split();
foreach (string whirred in subLines)
{
if (String.IsNullOrEmpty(whirred)) continue;
slAllDoc1Words.Add(whirred);
}
}
iCountOfWordsInDoc1 = slAllDoc1Words.Count();
sDoc1PhraseToSearchForInDoc2 = slAllDoc1Words[iSearchStartIndex] + ' ' + slAllDoc1Words[iSearchEndIndex];
while (iLastWordIndexReached < iCountOfWordsInDoc1 - 1)
{
sFoundPhrase = string.Empty;
// Search for the phrase from doc1 in doc2;
found = doc2StrArray.Contains(sDoc1PhraseToSearchForInDoc2);
if (found)
{
sFoundPhrase = sDoc1PhraseToSearchForInDoc2;
iSearchEndIndex++;
sDoc1PhraseToSearchForInDoc2 = sDoc1PhraseToSearchForInDoc2 + ' ' + slAllDoc1Words[iSearchEndIndex];
}
else //if not found, inc vals of BOTH int args and, if sFoundPhrase not null, assign to sDoc1PhraseToSearchForInDoc2 again.
{
iSearchStartIndex = iSearchEndIndex;
iSearchEndIndex = iSearchStartIndex + 1;
if (!string.IsNullOrWhiteSpace(sFoundPhrase)) // add the previous found phrase if there was one
{
slPhrasesFoundInBothDocs.Add(sFoundPhrase);
}
sDoc1PhraseToSearchForInDoc2 = slAllDoc1Words[iSearchStartIndex] + ' ' + slAllDoc1Words[iSearchEndIndex];
} // if/else
iLastWordIndexReached = iSearchEndIndex;
} // while
} // try
catch (Exception ex)
{
MessageBox.Show("FindAndStorePhrasesFoundInBothDocs(); iSearchStartIndex = " + iSearchStartIndex.ToString() + "iSearchEndIndex = " + iSearchEndIndex.ToString() + " iLastWordIndexReached = " + iLastWordIndexReached.ToString() + " " + ex.Message);
}
}
doc2StrArray does contain the phrase sought, so why does doc2StrArray.Contains(sDoc1PhraseToSearchForInDoc2) fail?
This should do what you want:
found = Array.FindAll(doc2StrArray, s => s.Contains(sDoc1PhraseToSearchForInDoc2));
In List<T>, Contains() looking for an T, Here in your code to found be true must have all the text in particular index (NOT part of it).
Try this
var _list = doc2StrArray.ToList();
var found = _list.FirstOrDefault( w => w.Contains( sDoc1PhraseToSearchForInDoc2 ) ) != null;
Me and my buddy Xylophone have been at this for hours and cant figure this out, any help would be appreciated. I'm basically trying to read all the text from that URL and search for a keyword.
if (comboBoxEdit1.Text == "Hello")
{
label2.Text = "Current Status: Searching...";
this.dataGridView3.ScrollBars = ScrollBars.None;
this.dataGridView3.MouseWheel += new MouseEventHandler(mousewheel);
dataGridView3.Rows.Clear();
string line;
int row = 0;
List<String> LinesFound = new List<string>();
StreamReader file = new StreamReader("https://pastebin.com/raw/fWxKdRjN");
while ((line = file.ReadLine()) != null)
{
if (line.Contains(textEdit1.Text))
{
string[] Columns = line.Split(':');
dataGridView3.Rows.Add(line);
for (int i = 0; i < Columns.Length; i++)
{
dataGridView3[i, row].Value = Columns[i];
}
row++;
label2.Text = "Current Status: " + dataGridView3.Rows.Count + " Matche(s) Found";
}
else if (dataGridView3.RowCount == 0)
{
label2.Text = "Current Status: No Matche(s) Found";
}
}
}
You are doing it all wrong, if you want to read and pars the html content of the web page, you need to fetch the page using httpClient, or better take look at this library https://html-agility-pack.net/
We can use regular expression to check if 'raw' exist in the URL.
Regex.Matches() function will return an array with all occurrence of the match.
We can then use count property to find the no of occurence.
Regular expression to match raw in a url:(raw)
Below is the working code snippet:
public static void Main()
{
string pattern = #"(raw)";
Regex rgx = new Regex(pattern);
string url = "https://pastebin.com/raw/fWxKdRjN";
if (rgx.Matches(url).Count>0){
Console.WriteLine(Current Status: " + rgx.Matches(url).Count + " Matche(s) Found");
}
else {
Console.WriteLine("Current Status: No Matche(s) Found");
}
}
I'm back at it again with another question, this time with regards to editing text files. My home work is as follow
Write a program that reads the contents of a text file and inserts the line numbers at the beginning of each line, then rewrites the file contents.
This is what I have so far, though I am not so sure if this is the most efficient way of doing it. I've only started learning on handling text files at the moment.
static void Main(string[] args)
{
string fileName = #"C:\Users\Nate\Documents\Visual Studio 2015\Projects\Chapter 15\Chapter 15 Question 3\Chapter 15 Question 3\TextFile1.txt";
StreamReader reader = new StreamReader(fileName);
int lineCounter = 0;
List<string> list = new List<string>();
using (reader)
{
string line = reader.ReadLine();
while (line != null)
{
list.Add("line " + (lineCounter + 1) + ": " + line);
line = reader.ReadLine();
lineCounter++;
}
}
StreamWriter writer = new StreamWriter(fileName);
using (writer)
{
foreach (string line in list)
{
writer.WriteLine(line);
}
}
}
your help would be appreciated!
thanks once again. :]
this should be enough (in case the file is relatively small):
using System.IO;
(...)
static void Main(string[] args)
{
string fileName = #"C:\Users\Nate\Documents\Visual Studio 2015\Projects\Chapter 15\Chapter 15 Question 3\Chapter 15 Question 3\TextFile1.txt";
string[] lines = File.ReadAllLines(fileName);
for (int i = 0; i< lines.Length; i++)
{
lines[i] = string.Format("{0} {1}", i + 1, lines[i]);
}
File.WriteAllLines(fileName, lines);
}
I suggest using Linq, use File.ReadLinesto read the content.
// Read all lines and apply format
var formatteLines = File
.ReadLines("filepath") // read lines
.Select((line, i) => string.Format("line {0} :{1} ", line, i+1)); // format each line.
// write formatted lines to either to the new file or override previous file.
File.WriteAllLines("outputfilepath", formatteLines);
Just one loop here. I think it will be efficient.
class Program
{
public static void Main()
{
string path = Directory.GetCurrentDirectory() + #"\MyText.txt";
StreamReader sr1 = File.OpenText(path);
string s = "";
int counter = 1;
StringBuilder sb = new StringBuilder();
while ((s = sr1.ReadLine()) != null)
{
var lineOutput = counter++ + " " + s;
Console.WriteLine(lineOutput);
sb.Append(lineOutput);
}
sr1.Close();
Console.WriteLine();
StreamWriter sw1 = File.AppendText(path);
sw1.Write(sb);
sw1.Close();
}
I have a file that is being created based on the items in a Repeater control if the radioButton for each item is "Yes". My issue that if the file is empty, it is still being created. I have tried FileName.Length > 0 and other possible solutions but I get errors that the file can not be found. I am sure the issue is within my logic but I cant see where. Any ideas?
protected void btnContinue_Click(object sender, EventArgs e)
{
string JobName;
string FileName;
StreamWriter sw;
string Name, Company, Date;
JobName = TYest + "_" + System.DateTime.Now;
JobName = JobName.Replace(":", "").Replace("/", "").Replace(" ", "");
FileName = JobName + ".txt";
sw = new StreamWriter(C: +"/" + FileName, false, Encoding.GetEncoding(1250));
foreach ( RepeaterItem rpItems in rpGetData.Items )
{
RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");
if ( rbYesNo.SelectedItem.Text == "Yes" )
{
Label rName = (Label)rpItems.FindControl("lblName");
Label rCompany = (Label)rpItems.FindControl("lblCompany");
Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
Name = rName.Text;
Company = rCompany.Text;
Date = System.DateTime.Now.ToString("MM/dd/yyyy");
sw.WriteLine("Name," + Name);
sw.WriteLine("Company," + Company);
sw.WriteLine("Date," + Date);
sw.WriteLine("*PRINTLABEL");
}
sw.Flush();
sw.Dispose();
if ( File.Exists("C:/" + FileName) )
{
try
{
File.Copy(+"C:/" + FileName, LoftwareDropPath + FileName, true);
}
catch ( Exception ex )
{
string msgE = "Error";
msgE += ex.Message;
throw new Exception(msgE);
}
}
else
{
//Do something if temp file not created properly
lblMessage.Text = "An error has occurred. Plese see your host to get a printed name badge.";
}
MessageBox messageBox = new MessageBox();
messageBox.MessageTitle = "Printed?";
messageBox.MessageText = "If not, please see host.";
Literal1.Text = messageBox.Show(this);
}
}
sounds like you want to detect if a file is empty. Use:
long length = new System.IO.FileInfo(path).Length;
if(length == 0)....
FileName.Length just tells you how long the file name is - not usefule
Why not check if the file exists first? That should solve your exception problems! If you want to know if the file is empty I would recommend checking what you're writing to the file and making sure it's not all empty and THEN write to the file if you actually have content?
if(File.Exists(File))
{
if(new FileInfo(File).Length > 0)
{
//Do Stuff.
}
}
How about this:
StreamWriter sw = null;
string Name, Company, Date;
JobName = TYest + "_" + System.DateTime.Now;
JobName = JobName.Replace(":", "").Replace("/", "").Replace(" ", "");
FileName = #"C:\" + JobName + ".txt";
try
{
foreach (RepeaterItem rpItems in rpGetData.Items)
{
RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");
if (rbYesNo.SelectedItem.Text == "Yes")
{
if (null == sw)
sw = new StreamWriter(FileName, false, Encoding.GetEncoding(1250));
Label rName = (Label)rpItems.FindControl("lblName");
Label rCompany = (Label)rpItems.FindControl("lblCompany");
Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
Name = rName.Text;
Company = rCompany.Text;
Date = System.DateTime.Now.ToString("MM/dd/yyyy");
sw.WriteLine("Name," + Name);
sw.WriteLine("Company," + Company);
sw.WriteLine("Date," + Date);
sw.WriteLine("*PRINTLABEL");
}
}
finally
{
if (null != sw)
{
sw.Flush();
sw.Dispose();
}
}
Build your FileName completely once so that you know it is always the same. Then only create your StreamWriter if something is going to be written. Also, use a try..finally to make sure your code to free your resources is always hit.
You should change it to only write and create the file when you have some data to write.
A simple way of doing this is to store everything memory with something like a StringBuilder, then afterwards write the contents of the string builder to the file if there is something to write:
var sb = new StringBuilder();
foreach (RepeaterItem rpItems in rpGetData.Items)
{
RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");
if (rbYesNo.SelectedItem.Text == "Yes")
{
// ..omitted..
sb.AppendLine("Name," + Name);
sb.AppendLine("Company," + Company);
sb.AppendLine("Date," + Date);
sb.AppendLine("*PRINTLABEL");
}
}
if (sb.Length > 0)
{
File.WriteAllText(FileName, sb.ToString(), Encoding.GetEncoding(1250));
}
You can check whether any items are eligible for saving before opening the stream writer like this:
var itemsToBeSaved = rpGetData.Items
Where(ri => ((RadioButtonList)ri.FindControl("rbBadge")).SelectedItem.Text == "Yes");
if (itemsToBeSaved.Any()) {
string path = #"C:\" + FileName;
using (var sw = new StreamWriter(path, false, Encoding.GetEncoding(1250))) {
foreach (RepeaterItem rpItems in itemsToBeSaved) {
Label rName = (Label)rpItems.FindControl("lblName");
Label rCompany = (Label)rpItems.FindControl("lblCompany");
Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
Name = rName.Text;
Company = rCompany.Text;
Date = System.DateTime.Now.ToString("MM/dd/yyyy");
sw.WriteLine("Name," + Name);
sw.WriteLine("Company," + Company);
sw.WriteLine("Date," + Date);
sw.WriteLine("*PRINTLABEL");
}
} // Flushes, Closes und Disposes the stream automatically.
}
The first statement prepares a filtered enumeration of repeater items containing only the ones to be saved. itemsToBeSaved.Any() tests if this enumeration contains at least one item. This enumeration is then reused in the foreach statement. Therefore it is not necessary to check the conditions again.
The using statement takes care of closing the stream in all situations, even if an exception should occur while writing to the file. I also declared the stream writer in the using statement. Therefore you can delete your declaration StreamWriter sw = null;.
Also note the expression #"C:\" + FileName. The # makes the string constant a verbatim string. This means that the usual escape character '\' loses its meaning and is used as is. Path.Combine(...) does not work here, since it does not add the path separator after a drive letter.
I am currently using lucene.net to search the content of files for keyword search. I am able to get the results correctly but I have a scenario where I need to display the keywords found in a particular file.
There are two different files containing "karthik" and "steven", and if I search for "karthik and steven" I am able to get both the files displayed. If I search only for "karthik" and "steven" separately, only the respective files are getting displayed.
When I search for "karthik and steven" simultaneously I get both the files in the result as I am displaying the filename alone, and now I need to display the particular keyword found in that particular file as a record in the listview.
Public bool StartSearch()
{
bool bResult = false;
Searcher objSearcher = new IndexSearcher(mstrIndexLocation);
Analyzer objAnalyzer = new StandardAnalyzer();
try
{
//Perform Search
DateTime dteStart = DateTime.Now;
Query objQuery = QueryParser.Parse(mstrSearchFor, "contents", objAnalyzer);
Hits objHits = objSearcher.Search(objQuery, objFilter);
DateTime dteEnd = DateTime.Now;
mlngTotalTime = (Date.GetTime(dteEnd) - Date.GetTime(dteStart));
mlngNumHitsFound = objHits.Length();
//GeneratePreviewText(objQuery, mstrSearchFor,objHits);
//Generate results - convert to XML
mstrResultsXML = "";
if (mlngNumHitsFound > 0)
{
mstrResultsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Results>";
//Loop through results
for (int i = 0; i < objHits.Length(); i++)
{
try
{
//Get the next result
Document objDocument = objHits.Doc(i);
//Extract the data
string strPath = objDocument.Get("path");
string strFileName = objDocument.Get("name");
if (strPath == null) { strPath = ""; }
string strLastWrite = objDocument.Get("last_write_time");
if (strLastWrite == null)
strLastWrite = "unavailable";
else
{
strLastWrite = DateField.StringToDate(strLastWrite).ToShortDateString();
}
double dblScore = objHits.Score(i) * 100;
string strScore = String.Format("{0:00.00}", dblScore);
//Add results as an XML row
mstrResultsXML += "<Row>";
//mstrResultsXML += "<Sequence>" + (i + 1).ToString() + "</Sequence>";
mstrResultsXML += "<Path>" + strPath + "</Path>";
mstrResultsXML += "<FileName>" + strFileName + "</FileName>";
//mstrResultsXML += "<Score>" + strScore + "%" + "</Score>";
mstrResultsXML += "</Row>";
}
catch
{
break;
}
}
//Finish off XML
mstrResultsXML += "</Results>";
//Build Dataview (to bind to datagrid
DataSet objDS = new DataSet();
StringReader objSR = new StringReader(mstrResultsXML);
objDS.ReadXml(objSR);
objSR = null;
mobjResultsDataView = new DataView();
mobjResultsDataView = objDS.Tables[0].DefaultView;
}
//Finish up
objSearcher.Close();
bResult = true;
}
catch (Exception e)
{
mstrError = "Exception: " + e.Message;
}
finally
{
objSearcher = null;
objAnalyzer = null;
}
return bResult;
}
Above is the code i am using for search and the xml i am binding to the listview, now i need to tag the particular keywords found in the respective document and display it in the listview as recordsss,simlar to the below listview
No FileName KeyWord(s)Found
1 Test.Doc karthik
2 Test2.Doc steven
i hope u guys undesrtood the question,
This depends on how your documents were indexed. You'll need to extract the original content, pass it through the analyzer to get the indexed tokens, and check which matches the generated query.
Just go with the Highlighter.Net package, part of contrib, which does this and more.