How to get the line of a string in a text file and change it with C# [duplicate] - c#

This question already has answers here:
How to find and replace text in a file
(7 answers)
Closed yesterday.
I want to find out the line of where the string exist in the text file and then change the line with another string
var location = "bla bla bla";
string fileContents = File.ReadAllText(location);
if (fileContents.Contains("LastSession\tcallsign"))
{
// here i want to save the line info of the "LastSession\tcallsing into a string variable then replace the string with another string
}

You could use:
StringComparison comparison = StringComparison.Ordinal; // change to OrdinalIgnoreCase if desired
string searchString = "LastSession\tcallsign";
string replaceString = "new value";
var newLines = File.ReadLines(location)
.Select(GetNewLineInfo)
.Select(x => x);
// if you want to know the line-numbers
var matchLineNumbers = newLines.Where(x => x.Contains).Select(x => x.LineNumber);
// if you want to rewrite the file with the new lines:
File.WriteAllLines(location, newLines.Select(x => x.NewLine));
(bool Contains, string NewLine, int LineNumber) GetNewLineInfo(string line, int index)
{
bool contains = line.IndexOf(searchString, comparison) >= 0;
return (contains, contains ? line.Replace(searchString, replaceString) : line, index + 1);
}

Related

How to validate or compare string by omitting certain part of it

I have a string as below
"a1/type/xyz/parts"
The part where 'xyz' exists is dynamic and varies accordingly at any size. I want to compare just the two strings are equal discarding the 'xyz' portion exactly.
For example I have string as below
"a1/type/abcd/parts"
Then my comparison has to be successful
I tried with regular expression as below. Though my knowledge on regular expressions is limited and it did not work. Probably something wrong in the way I used.
var regex = #"^[a-zA-Z]{2}/\[a-zA-Z]{16}/\[0-9a-zA-Z]/\[a-z]{5}/$";
var result = Regex.Match("mystring", regex).Success;
Another idea is to get substring of first and last part omitting the unwanted portion and comparing it.
The comparison should be successful by discarding certain portion of the string with effective code.
Comparison successful cases
string1: "a1/type/21412ghh/parts"
string2: "a1/type/eeeee122ghh/parts"
Comparison failure cases:
string1: "a1/type/21412ghh/parts"
string2: "a2/type/eeeee122ghh/parts/mm"
In short "a1/type/abcd/parts" in this part of string the non-bold part is static always.
Honestly, you could do this using regex, and pull apart the string. But you have a specified delimiter, just use String.Split:
bool AreEqualAccordingToMyRules(string input1, string input2)
{
var split1 = input1.Split('/');
var split2 = input2.Split('/');
return split1.Length == split2.Length // strings must have equal number of sections
&& split1[0] == split2[0] // section 1 must match
&& split1[1] == split2[1] // section 2 must match
&& split1[3] == split2[3] // section 4 must match
}
You can try Split (to get parts) and Linq (to exclude 3d one)
using System.Linq;
...
string string1 = "a1/type/xyz/parts";
string string2 = "a1/type/abcd/parts";
bool result = string1
.Split('/') // string1 parts
.Where((v, i) => i != 2) // all except 3d one
.SequenceEqual(string2 // must be equal to
.Split('/') // string2 parts
.Where((v, i) => i != 2)); // except 3d one
Here's a small programm using string functions to compare the parts before and after the middle part:
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine(CutOutMiddle("a1/type/21412ghh/parts"));
Console.WriteLine("True: " + CompareNoMiddle("a1/type/21412ghh/parts", "a1/type/21412ghasdasdh/parts"));
Console.WriteLine("False: " + CompareNoMiddle("a1/type/21412ghh/parts", "a2/type/21412ghh/parts/someval"));
Console.WriteLine("False: " + CompareNoMiddle("a1/type/21412ghh/parts", "a1/type/21412ghasdasdh/parts/someappendix"));
}
private static bool CompareNoMiddle(string s1, string s2)
{
var s1CutOut = CutOutMiddle(s1);
var s2CutOut = CutOutMiddle(s2);
return s1CutOut == s2CutOut;
}
private static string CutOutMiddle(string val)
{
var fistSlash = val.IndexOf('/', 0);
var secondSlash = val.IndexOf('/', fistSlash+1);
var thirdSlash = val.IndexOf('/', secondSlash+1);
var firstPart = val.Substring(0, secondSlash);
var secondPart = val.Substring(thirdSlash, val.Length - thirdSlash);
return firstPart + secondPart;
}
}
returns
a1/type/parts
True: True
False: False
False: False
This solution should cover your case, as said by others, if you have a delimiter use it. In the function below you could change int skip for string ignore or something similar and within the comparison loop if(arrayStringOne[i] == ignore) continue;.
public bool Compare(string valueOne, string valueTwo, int skip) {
var delimiterOccuranceOne = valueOne.Count(f => f == '/');
var delimiterOccuranceTwo = valueTwo.Count(f => f == '/');
if(delimiterOccuranceOne == delimiterOccuranceTwo) {
var arrayStringOne = valueOne.Split('/');
var arrayStringTwo = valueTwo.Split('/');
for(int i=0; i < arrayStringOne.Length; ++i) {
if(i == skip) continue; // or instead of an index you could use a string
if(arrayStringOne[i] != arrayStringTwo[i]) {
return false;
}
}
return true;
}
return false;
}
Compare("a1/type/abcd/parts", "a1/type/xyz/parts", 2);

Split string with a comma without spliting inside "" with c# only [duplicate]

This question already has answers here:
split a comma-separated string with both quoted and unquoted strings [duplicate]
(16 answers)
Closed 5 years ago.
How to split a string with a comma and don't split inside - "" with c# only.
For example this string "aa","b,b","asdds","sd,fd,sd,,f"
To this array/list - aa,b,b,asdds,sd,fd,sd,,f
string s = "\"aa\",\"b,b\",\"asdds\",\"sd,fd,sd,,f\""; // The string (\" = ") when write it inside string
List<string> s1 = new List<string>(); // List of the strings without the , and the "
string s2 = ""; // string for adding into the list
bool
first = false, // If arrive to the first "
second = false; // If arrive to the second "
foreach (char c in s) // Move over every char in the string
{
if (second) // If reach the second
{
s1.Add(s2); // Add the string to the list
s2 = ""; // Make s2 ready for new string
first = false; // Make first be ready for another string
second = false; // Make second be ready for another string
}
if (first) // If the string in the quotemark started
{
if (c == '"') // If the string in the quotemark ended
{
second = true; // Reach the second quotemark
}
else // If the string didn't end
{
s2 += c; // Add the char to the string
}
}
if (c == '"' && !first && !second) // If the string just reach the first quotemark in a string
{
first = true; // Reach the first quotemark
}
}
if (second&&first) //For the last string that missed at the end
{
s1.Add(s2); // Add the string to the list
}
string sample = "aa","b,b","asdds","sd,fd,sd,,f";
sample = sample.Replace("\",\", "&");
string[] targetA = sample.Split('&');

split string and store it in another variable in c# [duplicate]

This question already has answers here:
Split string using backslash
(3 answers)
Closed 5 years ago.
How to Read character after '\':
string PrName = "software\Plan Mobile";
First of all, do not forget #:
string PrName = #"software\Plan Mobile";
Next, if you want just the tail only (i.e. "Plan Mobile") then Substring will do:
// if no '\' found, the entire string will be return
string tail = PrName.Substring(PrName.IndexOf('\\') + 1);
If you want both (all parts), try Split:
// parts[0] == "software"
// parts[1] == "Plan Mobile"
string[] parts = PrName.Split('\\');
Try this:
char charToFind = '\';
string PrName = "software\Plan Mobile";
int indexOfChar = PrName.IndexOf(charToFind);
if (indexOfChar >= 0)
{
string result = PrName.Substring(indexOfChar + 1);
}
Output: result = "Plan Mobile"
I think, you want to split string
string s = "software\Plan Mobile";
// Split string on '\'.
string[] words = s.Split('\');
foreach (string word in words)
{
Console.WriteLine(word);
}
Output:
software
Plan mobile

How to check if a string contains only # [duplicate]

This question already has answers here:
Check If String Contains All "?"
(8 answers)
Closed 9 years ago.
I have a string like "# # # # #"
another string like "123 # abc # xyz"
I need to check if the string contains only # .How to achieve this.
I tried using contains ,but this does not work .
Providing that the String is not null, the possible solution can be:
String text = "123#abc#xyz";
Boolean result = text.All((x) => x == '#');
In case the white spaces should be ignored (e.g. "# # # # #" considered being the right string)
String text = "123#abc#xyz";
Boolean result = text.All((x) => x == '#' || Char.IsWhiteSpace(x));
bool IsSharpOnly(string str)
{
for(int i = 0; i < str.Length ; i++)
{
if (str[i] != '#')
return false;
}
return true;
}
Another solution with a Regex:
Regex r = new Regex("^#+$");
bool b1 = r.IsMatch("asdas#asdas");
bool b2 = r.IsMatch("#####");
Edit
Was not sure if white space should be ignored or not, if so:
Regex r = new Regex("^[\\s*#+]+$");
With a regular expression?
Like this: "([0-9]+)|([a-z]+)"
you can check if the input string does not match.
For instance for the string contains '#' only:
String text = "123#abc#xyz";
Boolean result = Regex.Match(text, "^#*$").Success;
Try this,
string ss = "##g#";
if ((ss.Split('#').Length - 1).Equals(ss.Length))
{
//Contains only #
}
You can also try this:
private bool CheckIfStringContainsOnlyHash(string value)
{
return !value.Where(a => !string.IsNullOrWhiteSpace(a.ToString()) && a != '#').Select(a => true).FirstOrDefault();
}
Try the below code
string txt = "123#abc#xyz";
if (!txt.Any((X) => X != '#'))
{
//Contains only '#'
}
Dmitry's example is probably the most elegant, but something like this could work too (again assuming the input has been null checked):
string test = "#####";
return test.Replace("#", "").Length == 0;
EDIT: picking up on the discussion about ignoring whitespace too, we could use:
string test = "#####";
return String.IsNullOrWhiteSpace(test.Replace("#", ""));
this is also a solution
String data= "###########";
bool isAllSame = data.All(d => d == '#');
if(isAllSame)
{
// code when string contain only #
}

Pattern based string parse

When I need to stringify some values by joining them with commas, I do, for example:
string.Format("{0},{1},{3}", item.Id, item.Name, item.Count);
And have, for example, "12,Apple,20".
Then I want to do opposite operation, get values from given string. Something like:
parseFromString(str, out item.Id, out item.Name, out item.Count);
I know, it is possible in C. But I don't know such function in C#.
Yes, this is easy enough. You just use the String.Split method to split the string on every comma.
For example:
string myString = "12,Apple,20";
string[] subStrings = myString.Split(',');
foreach (string str in subStrings)
{
Console.WriteLine(str);
}
Possible implementations would use String.Split or Regex.Match
example.
public void parseFromString(string input, out int id, out string name, out int count)
{
var split = input.Split(',');
if(split.length == 3) // perhaps more validation here
{
id = int.Parse(split[0]);
name = split[1];
count = int.Parse(split[2]);
}
}
or
public void parseFromString(string input, out int id, out string name, out int count)
{
var r = new Regex(#"(\d+),(\w+),(\d+)", RegexOptions.IgnoreCase);
var match = r.Match(input);
if(match.Success)
{
id = int.Parse(match.Groups[1].Value);
name = match.Groups[2].Value;
count = int.Parse(match.Groups[3].Value);
}
}
Edit: Finally, SO has a bunch of thread on scanf implementation in C#
Looking for C# equivalent of scanf
how do I do sscanf in c#
If you can assume the strings format, especially that item.Name does not contain a ,
void parseFromString(string str, out int id, out string name, out int count)
{
string[] parts = str.split(',');
id = int.Parse(parts[0]);
name = parts[1];
count = int.Parse(parts[2]);
}
This will simply do what you want but I would suggest you add some error checking. Better still consider serializing/deserializing to XML or JSON.
Use Split function
var result = "12,Apple,20".Split(',');

Categories