I have a filename of document erwin_01problem.doc, What i want here is the if a filename does not contain a space between 01problem (erwin_01problem.doc). I find the index of problem and replace it with " ". The output will be erwin_01 problem.doc
Here is the code that i try but still I wasn't able to put a space between 01 and problem.
if (!string.IsNullOrEmpty(job.ProblemPath))
{
job.HasProblemFile = true;
var problemDocFname = Path.GetFileName(job.ProblemPath);
if (!Regex.IsMatch(problemDocFname, #"\sproblem\.doc$"))
{
ProgM.JobStatus = "Checking space between filename and problem...";
Thread.Sleep(1000);
problemDocFname = problemDocFname.Insert(problemDocFname.IndexOf("problem.doc", StringComparison.Ordinal), " ");
//problemDocFname = problemDocFname.Replace("problem", " problem");
}
problemDocFname = Path.Combine(job.FilePath, problemDocFname);
var docProblemCount = 0;
ProgM.JobStatus = "Correcting the Format of Problem Doc...";
Thread.Sleep(1000);
MicrosoftWord.CorrectProblemDocFormatting(problemDocFname, ref docProblemCount);
}
jobs.Add(job);
I belive you don't really need regular expressions. You can just do something like:
string key = "problem.doc";
if (problemDocFname.EndsWith(key) && problemDocFname.Length > key.Length)
{
problemDocFname.Replace(key, " problem.doc");
}
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");
}
}
So I have a long string containing pointy brackets that I wish to extract text parts from.
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
I want to be able to get this
1 = "text1"
27 = "text27"
3 = "text3"
How would I obtain this easily? I haven't been able to come up with a non-hacky way to do it.
Thanks.
Using basic XmlReader and some other tricks to do wrapper to create XML-like data, I would do something like this
string xmlString = "<1>text1</1><27>text27</27><3>text3</3>";
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>";
string key = "";
List<KeyValuePair<string,string>> kvpList = new List<KeyValuePair<string,string>>(); //assuming the result is in the KVP format
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString))){
bool firstElement = true;
while (xmlReader.Read()) {
if (firstElement) { //throwing away root
firstElement = false;
continue;
}
if (xmlReader.NodeType == XmlNodeType.Element) {
key = xmlReader.Name.Substring(1); //cut of "o"
} else if (xmlReader.NodeType == XmlNodeType.Text) {
kvpList.Add(new KeyValuePair<string,string>(key, xmlReader.Value));
}
}
}
Edit:
The main trick is this line:
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>"; //wrap to make this having single root, o is put to force the tagName started with known letter (comment edit suggested by Mr. chwarr)
Where you first replace all opening pointy brackets with itself + char, i.e.
<1>text1</1> -> <o1>text1<o/1> //first replacement, fix the number issue
and then reverse the sequence of all the opening point brackets + char + forward slash to opening point brackets + forward slash + char
<o1>text1<o/1> -> <o1>text1</o1> //second replacement, fix the ending tag issue
Using simple WinForm with RichTextBox to print out the result,
for (int i = 0; i < kvpList.Count; ++i) {
richTextBox1.AppendText(kvpList[i].Key + " = " + kvpList[i].Value + "\n");
}
Here is the result I get:
This is far from bulletproof, but you could use a combination of split and Regex matching:
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
string[] results = exampleString.Split(new string[] { "><" }, StringSplitOptions.None);
Regex r = new Regex(#"^<?(\d+)>([^<]+)<");
foreach (string result in results)
{
Match m = r.Match(result);
if (m.Success)
{
string index = m.Groups[1].Value;
string value = m.Groups[2].Value;
}
}
The most non-bulletproof example I can think of is if your text contains a "<", that would pretty much break this.
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.
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();