Can I shorten this code with a loop in C#? - c#

I have this code written in C# but looks kind of "bad" and I would like to shorten it somehow and keep it clean and simple.
All this code works pretty fine but I want to know if there's any other way I can achieve the same thing.
EDIT: I forgot to mention that the firstLine has a bad date format attached with it, so it is like this: "This_is_my_first_line_20220126". So I split the string and then only join it with the corrected date. The problem is that I can never know how long the new string would be and I don't want to handle the code like this and go up to 100 parts.
Here's my code:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
string firstLine = lines.FirstOrDefault();
//note: firstLine looks like this: This_is_my_first_line_20220126
string[] sub = firstLine.Split('_');
string name="";
if(sub.Length==2)
name = sub[0]+"_"+sub[1]+"_"+correctDate;
else if(sub.Length==3)
name = sub[0]+"_"+sub[1]+"_"+sub[2]+"_"correctDate;
...
else if(sub.Length==20)
name = sub[0]+"_"+ ... "_" + sub[19];
Now, my final name value should be "This_is_my_line_26012022" but I want it to depend on the length of the given string. So far I know that the maximum length would go up to 20 but I don't want my code to look like this. Can I shorten it somehow?

you can find the LastIndexOf the underscore and drop the date by using Substring:
string firstLine = "This_is_my_first_line_20220126";
string correctDate = "26012022";
string correctString = firstLine.Substring(0, firstLine.LastIndexOf("_") + 1) + correctDate;

Still a little perplexed with the split aproach, but this a way to join back all elements
string name = string.Join("_", sub.Take(sub.Length - 1).Append(correctDate));
Or use the substring method (and no need of all that split & join)
name = firstLine.Substring(0, firstLine.LastIndexOf("_") +1) + correctDate;

I forgot to mention that firstLine has a bad date format like "This_is_my_Line_20220125"
If you want to correct just the first line:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
lines[0] = lines[0][..^8] + correctDate;
[..^8] uses C# 9's "indices and ranges" feature, that allows for a more compact way of taking a substring. It means "from the start of the string, up to the index 8 back from the end of the string".
If you get a wiggly line and possibly a messages like "... is not available in C# version X" you can use the older syntax, which would be more like lines[0] = lines[0].Remove(lines[0].Length - 8) + correctDate;
If you want to correct all lines:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
for(int x = 0; x < lines.Length; x++)
lines[x] = lines[x][..^8] + correctDate;
If the incorrect date isn't always 8 characters long, you can use LastIndexOf('_') to locate the last _, and snip it to that point

Related

How to get second value via c# StartsWith() method

string text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
How to get how many times the text **David Diaz occurs in the string text?
UPDATED MY QUESTION
By using StartWhith you can check if the string starts whit ** if it is take the first two words of the string whits will represent the name
string text = "**David Diaz He went to school.";
if (text.StartsWith("**"))
{
var names = text.Split(' ')
.Take(2)
.ToArray();
var fullName = names[0] + " " + names[1];
}
UPDATE
As you said in the commend you want to look how many David Diaz occurs in one string, you can use regex for that.
string text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
int matches = Regex.Matches(
text,
#"(?:\S+\s)?\S*David Diaz\S*(?:\s\S+)?",
RegexOptions.IgnoreCase
).Count;
var text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
var pos = 0;
var num = 0;
var search = "**David Diaz";
while ((pos = text.IndexOf(search, pos)) > -1)
{
num ++;
pos += search.Length;
}
Console.WriteLine(num);
you can try out this in dotnetfiddle
Updated Answer:
It sounds like you want to find the number of times a substring exists in your text. For that, you'll want to use RegEx.Matches, as explained in this answer: https://stackoverflow.com/a/3016577/682840
or LINQ, as explained in this answer: https://stackoverflow.com/a/541994/682840
Original Answer:
.StartsWith returns true/false if the string begins with the search string you provide. If you're wanting to know where a substring exists within your text, you'll need to use .IndexOf or a Regular Expression for more advanced scenarios.
IndexOf will return the location in the text where your provided search string starts (or -1 if it isn't found).

String Find & Replace Method

I need to locate a specific part of a string value like the one below, I need to alter the "Meeting ID" to a specific number.
This number comes from a dropdownlist of multiple numbers, so I cant simply use find & replace. As the text could change to one of multiple numbers before the user is happy.
The "0783," part of the string never changes, and "Meeting ID" is always followed by a ",".
So i need to get to "0783, INSERT TEXT ," and then insert the new number on the Index Changed event.
Here is an example :-
Business Invitation, start time, M Problem, 518-06-xxx, 9999 999
0783, Meeting ID, xxx ??
What is the best way of locating this string and replacing the test each time?
I hope this makes sense guys?
Okay, so there are several ways of doing this, however this seems to be a string you have control over so I'm going to say here's what you want to do.
var myString = string.Format("Business Invitation, start time, M Problem, 518-06-xxx, 9999 999 0783, {0}, xxx ??", yourMeetingId);
If you don't have control over it then you're going to have to be a bit more clever:
var startingIndex = myString.IndexOf("0783, ");
var endingIndex = myString.IndexOf(",", startingIndex + 6);
var pattern = myString.Substring(startingIndex + 6, endingIndex - (startingIndex + 6));
myString = myString.Replace(pattern, yourMeetingId);
You should store your "current" Meeting ID in a variable, changing it along with your user's actions, and then use that same global variable whenever you need the string.
This way, you don't have to worry about what's inside the string and don't need to mess with array indexes. You will also be safe from magic numbers / strings, which are bound to blow up in your face at some point in the future.
You can try with Regex.Replace method
string pattern = #"\d{3},";
Regex regex = new Regex(pattern);
var inputStr = "518-06-xxx, 9999 999 0783";
var replace = "..."
var outputStr = regex.Replace(inputStr, replace);
use Regex.Split by token "0783," then in the second string in the array return split by token "," the first element in the string array would be where you would insert new text. Then use string.Join to join the first split with "0783," and the join the second with ",".
string temp = "Business Invitation, start time, M Problem, 518-06-xxx, 9999 999 0783, Meeting ID, xxx ??";
string newID = "1234";
string[] firstSplits = Regex.Split(temp, "0783,");
string[] secondSplits = Regex.Split(firstSplits[1], ",");
secondSplits[0] = newID;
string #join = string.Join(",", secondSplits);
firstSplits[1] = #join;
string newString = string.Join("0783,", firstSplits);

C# string.Replace doesn't work

Basically our Problem is:
We can't replace a string like this: 10003*
But we can replace a string like this: 10003
we want to replace a part of a string that looks like this: 10003*
This is our Code:
string text = sr2.ReadToEnd();
sr2.Close();
while (loop != lstTxt.Items.Count)
{
string SelectedItem = lstTxt.SelectedItem.ToString() + "*";
text = text.Replace(SelectedItem, "tietze111");
if (lstTxt.SelectedIndex < lstTxt.Items.Count - 1)
lstTxt.SelectedIndex++;
loop++;
}
sw2.Write(text);
But it doesn't work. When we leave out the * in the part to replace, it works. But we have to replace the * too. Do you know what we have to change?
It works when we use this:
string text = sr2.ReadToEnd();
sr2.Close();
while (loop != lstTxt.Items.Count)
{
string SelectedItem = lstTxt.SelectedItem.ToString(); // changed
text = text.Replace(SelectedItem, "tietze111");
if (lstTxt.SelectedIndex < lstTxt.Items.Count - 1)
lstTxt.SelectedIndex++;
loop++;
}
sw2.Write(text);
--
using (var sr2 = new StreamReader(Application.StartupPath + #"\website\Dehler 22 ET.htm", Encoding.Default))
{
using (var sw2 = new StreamWriter(tempFile, true, Encoding.Default))
We are using this because the file is still in ASCII. Maybe that is the problem.
How do we solve this?
Fix the following line,
string SelectedItem = lstTxt.SelectedItem.Value;
You are taking the item and not the value.
Have you tried?
"[\*]"
Or
#"[*]"
The String.Replace(String,String) method doesn't do anything special with any characters. There is a character in your id that you are trying to replace is not the same as the one you are trying to match on. I would try copying the astrisk from the data source into your code and see if the problem still exists.
Your problem * is encoded in some other type. The Unicode value for asterisk U+002A
You could try this. Note Char.MinValue is technically a null value since you cannot have a blank Char.
In your case: lstTxt.SelectedItem.ToString() + '\u002A'.ToString();
If that doesn't work try removing (using different encoded values for *) to make sure you can actually find it in the string.
SomeString.Replace('\u002A', Char.MinValue);
OR
SomeString.Replace('\u002A'.ToString(), String.Empty);
I've ran into issues like this before and it ends up being a trial and error kind of thing until you get it right. Similar problem I had last summer C# String.Replace not finding / replacing Symbol (™, ®)

Remove characters after specific character in string, then remove substring?

I feel kind of dumb posting this when this seems kind of simple and there are tons of questions on strings/characters/regex, but I couldn't find quite what I needed (except in another language: Remove All Text After Certain Point).
I've got the following code:
[Test]
public void stringManipulation()
{
String filename = "testpage.aspx";
String currentFullUrl = "http://localhost:2000/somefolder/myrep/test.aspx?q=qvalue";
String fullUrlWithoutQueryString = currentFullUrl.Replace("?.*", "");
String urlWithoutPageName = fullUrlWithoutQueryString.Remove(fullUrlWithoutQueryString.Length - filename.Length);
String expected = "http://localhost:2000/somefolder/myrep/";
String actual = urlWithoutPageName;
Assert.AreEqual(expected, actual);
}
I tried the solution in the question above (hoping the syntax would be the same!) but nope. I want to first remove the queryString which could be any variable length, then remove the page name, which again could be any length.
How can I get the remove the query string from the full URL such that this test passes?
For string manipulation, if you just want to kill everything after the ?, you can do this
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.IndexOf("?");
if (index >= 0)
input = input.Substring(0, index);
Edit: If everything after the last slash, do something like
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.LastIndexOf("/");
if (index >= 0)
input = input.Substring(0, index); // or index + 1 to keep slash
Alternately, since you're working with a URL, you can do something with it like this code
System.Uri uri = new Uri("http://www.somesite.com/what/test.aspx?hello=1");
string fixedUri = uri.AbsoluteUri.Replace(uri.Query, string.Empty);
To remove everything before the first /
input = input.Substring(input.IndexOf("/"));
To remove everything after the first /
input = input.Substring(0, input.IndexOf("/") + 1);
To remove everything before the last /
input = input.Substring(input.LastIndexOf("/"));
To remove everything after the last /
input = input.Substring(0, input.LastIndexOf("/") + 1);
An even more simpler solution for removing characters after a specified char is to use the String.Remove() method as follows:
To remove everything after the first /
input = input.Remove(input.IndexOf("/") + 1);
To remove everything after the last /
input = input.Remove(input.LastIndexOf("/") + 1);
Here's another simple solution. The following code will return everything before the '|' character:
if (path.Contains('|'))
path = path.Split('|')[0];
In fact, you could have as many separators as you want, but assuming you only have one separation character, here is how you would get everything after the '|':
if (path.Contains('|'))
path = path.Split('|')[1];
(All I changed in the second piece of code was the index of the array.)
The Uri class is generally your best bet for manipulating Urls.
To remove everything before a specific char, use below.
string1 = string1.Substring(string1.IndexOf('$') + 1);
What this does is, takes everything before the $ char and removes it. Now if you want to remove the items after a character, just change the +1 to a -1 and you are set!
But for a URL, I would use the built in .NET class to take of that.
Request.QueryString helps you to get the parameters and values included within the URL
example
string http = "http://dave.com/customers.aspx?customername=dave"
string customername = Request.QueryString["customername"].ToString();
so the customername variable should be equal to dave
regards
I second Hightechrider: there is a specialized Url class already built for you.
I must also point out, however, that the PHP's replaceAll uses regular expressions for search pattern, which you can do in .NET as well - look at the RegEx class.
you can use .NET's built in method to remove the QueryString.
i.e., Request.QueryString.Remove["whatever"];
here whatever in the [ ] is name of the querystring which you want to
remove.
Try this...
I hope this will help.
You can use this extension method to remove query parameters (everything after the ?) in a string
public static string RemoveQueryParameters(this string str)
{
int index = str.IndexOf("?");
return index >= 0 ? str.Substring(0, index) : str;
}

string[] management

ok, so ill cut to the chase here. and to be clear, im looking for code examples where possible.
so, i have a normal string, lets say,
string mystring = "this is my string i want to use";
ok, now that i have my string, i split it by the space with
string[] splitArray = mystring.Split(new char[] { ' ' });
ok, so now i have splitArray[0] through splitArray[7].
now, i need to do some fancy things with the string that i normally wouldnt need to do.
here are a few:
i need to cut off the first word, so i am left with the other 7 words, so that i have something like:
string myfirstword = "this";
mystring = "is my string i want to use";
now, i will need to use mystring over and over again, using different parts of it at different times, and depending on the string i will have no idea how long, it will be. so i will give some examples of things ill need.
first, ill need to know, how many words are there (this is easy, just throwing it in)
second, ill need some way of using things like,
string secondword = splitArray[1];
string everythingAfterTheSecondWord = splitArray[2+];
if you noticed, i included a [2+] ... the + indicating that i want all strings in the array put back together, spaces in all, into a string. so for example,
string examplestring = "this is my example for my stack overflow question";
string[] splitArray2 = examplestring.Split(new char[] { ' ' });
now, if i called on splitArray2[4+] i would want a return of "for my stack overflow question". now obviously its not as simple as adding a + to a string array.. but thats what i need, and under the current situation i have tried many other easier ways that simply to not work.
ALSO, if i called on something like splitArray2[2-5] i would want, words 2 through 5 obviously.
Summary:
i need greater management of my string[] arrays, and i need to be able to find, every word after word *, need to be able to strip out random words in the string while leaving the rest of the string intact, and need to be able to find string m through n
Thanks!
Most of what you're looking for can be achieved with a List<string>. Briefly:
string mystring = "this is my string i want to use";
List<string> splitArray = new List<string>(mystring.Split(new char[] { ' ' }));
string firstWord = splitArray[0];
// mystring2 = "is my string i want to use"
splitArray.RemoveAt(0);
string mystring2 = String.Join(" ", splitArray.ToArray());
To do the more complicated things you describe with splitArray[2+] requires LINQ though, and hence .NET 3.5.
List<string> everythingAfterTheSecondWord = splitArray.Skip(2).ToList();
For splitArray[2-5]:
List<string> arraySlice = splitArray.Skip(2).Take(3).ToList();
Well, to do the "every word starting at word X" you could do this:
string newString = string.join(splitArray," ",x);
To get y words starting at x, do this:
string newString = string.join(splitArray," ",x,y);
To get the number of words:
int wordCount= splitArray.Length;
Putting it all together, words x-y goes like this:
string newString = string.join(splitArray," ",x, splitArray.Length-x+1);

Categories

Resources