c# get the matched value from an string array of a string - c#

i have a long string that I want to see if it matches anything from a string array
string line = "this is a banana testing quote.";
string[] searchList = new string[4] {"b", "quote", "tee", "obb"};
I will first need to find if the line contains any string from the searchList.
if(searchList.Any(line.Contains))
and it can check if there is any match from the searchList, in this case, it should be "quote". but the checking can only check if it contains without knowing which exact string from the string array is matched.
Is there any better way to get the matched value, eg: string matchedValue = "serachList[2] or string matchedValue = "quote" other than looping the whole string for checking again?
I cannot loop through the string array searchList one by one as I am reading a big log, I think it is faster and better to use.Any()

Related

How to get the char from a string that contains unicode escape sequence which starts with "\u"

I did quite a lot of researches but still could not figure it out. Here is an example, I got a string contains "\uf022" (a character from another language), how can I change the whole string into the char '\uf022'?
Update:
the string "\uf022" is retrieved during runtime (read from other sources) instead of directly putting a static character into the string.
For example:
string url = "https://somesite/files/abc\uf022def.pdf";
int i = url.IndexOf("\\");
string specialChar = url.substring(i, 6);
How do I get the char saved in the string specialChar?
I would like to use this char to do UTF-8 encoding and generate the accessible URL "https://somesite/files/abc%EF%80%A2def.pdf".
Thank you!
how can I change the whole string into the char '\uf022'?
Strictly speaking, you can't change the characters of the string you have (because strings are immutable), but you can make a new one that meets your demands..
var s = new string('\uf022', oldstring.Length);
Your title of your question reads slightly differently.. it sounds like you want a string that is only the F022 chars, i.e. if your string has 10 chars and only 3 of them are F022, you want just the 3.. which could be done by changing oldstring.Length above, into oldstring.Count(c => c == '\uf022')
..and if you mean your string is like "hello\uf022world" and you want it to be like "hello🍄world" then do
var s = oldstring.Replace("\\uf022", "\uf022");
If you have the \uf022 in a string (6 chars) and you want to replace it with its actual character, you can parse it to int and convert to char when you replace..
var oldstring = "hello\uf022world";
var given = "\uf022";
var givenParsed = ((char)Convert.ToInt32(given.Substring(2), 16)).ToString();
var s = oldstring.Replace(given, givenParsed);

Replace multiple strings from a textfile

I need to replace multiple strings in a textfile. This is my code:
List<string> list = new List<string>();
string Text = File.ReadAllText(temp);
list.Add(Text.Replace("name", name));
list.Add(Text.Replace("name2", name2));
list.Add(Text.Replace("1.0000", CR));
list.Add(Text.Replace("0.6590", CG));
list.Add(Text.Replace("0.0000", CB));
foreach (string txt in list)
{
File.WriteAllText(path, txt);
}
When I debug I can see the strings beeing replaced one after one, but when the next string is about to be replaced, the last string will then go back to its old value. Is there a way to replace multiple strings in a textfile?
You don't need a list for this, but you do need to save the changes in the resulting string each time you do a replacement, otherwise you lose the changes.
The Replace method returns a new string with the replacement, so you can chain the calls to Replace and it will end up returning a string with all your changes.
Here's an example:
string text = File.ReadAllText(temp)
.Replace("name", name)
.Replace("name2", name2)
.Replace("1.0000", CR)
.Replace("0.6590", CG)
.Replace("0.0000", CB);
File.WriteAllText(path, txt);

Comma Separated text file to Generic List

Having a bit of trouble with converting a comma separated text file to a generic list. I have a class (called "Customers") defined with the following attributes:
Name (string)
City (string)
Balance (double)
CardNumber (int)
The values will be stored in a text file in this format: Name,City, Balance, CarNumber e.g. John,Memphis,10,200789. There will be multiple lines of this. What I want to do is have each line be placed in a list item when the user clicks a button.
I've worked out I can break each line up using the .Split() method, but have no idea how to make the correct value go into the correct attribute of the list. (Please note: I know how to use get/set properties, and I am not allowed to use LINQ to solve the problem).
Any help appreciated, as I am only learning and have been working on this for a for while with no luck. Thanks
EDIT:
Sorry, it appears I'm not making myself clear. I know how to use .add.
If I have two lines in the text file:
A,B,1,2 and
C,D,3,4
What I don't know how to do is make the name "field" in the list item in position 0 equal "A", and the name "field" in the item in position 1 equal "C" and so on.
Sorry for the poor use of terminology, I'm only learning. Hope you understand what I'm asking (I'm sure it's really easy to do once you know)
The result of string.Split will give you an array of strings:
string[] lineValues = line.Split(',');
You can access values in an array by index:
string name = lineValues[0];
string city = lineValues[1];
You can convert strings to double or int using their respective Parse methods:
double balance = double.Parse(lineValues[2]);
int cardNumber = int.Parse(lineValues[3]);
You can instantiate the class and assign to it very simply:
Customer customerForCurrentLine = new Customer()
{
Name = name,
City = city,
Balance = balance,
CardNumber = cardNumber,
};
Simply loop over the lines, instantiate a Customer for that line, and add it to a variable you've created of the type List<Customer>
If you want your program to be bulletproof, you're going to have to do a lot of checking to skip over lines that don't have enough values, or that would fail to parse to the correct number type. For example, check lineValues.Length == 4 and use int.TryParse(...) and double.TryParse(...).
Read a file and split its text based on newline character. Then for total line count run a loop that will split based on comma and create a new object and insert values in its properties and add that object to a list.
This way
List<Customers> lst = new List<Customers>();
string[] str = System.IO.File.ReadAllText(#"C:\CutomersFile.txt")
.Split(new string[] { Environment.NewLine },
StringSplitOptions.None);
for (int i = 0; i < str.Length; i++)
{
string[] s = str[i].Split(',');
Customers c = new Customers();
c.Name = s[0];
c.City = s[1];
c.Balance = Convert.ToDouble(s[2]);
c.CardNumber = Convert.ToInt32(s[3]);
lst.Add(c);
}
BTW class name should be Customer and not Customers
Split() generates an array of strings in the order they appeared in the source string. Thus, if your name field is the first column in the CSV file, it will always be the first index in the array.
someCustomer.Name = splitResult[0];
And so on. You'll also need to investigate String.TryParse for your class's numerically typed properties.

how can i read specific block from text file

I need to read a block of data from this text. The block starts with the T|DataObject.EShop.Tic.TicVente| line and ends with T|DataObject.EShop.Tic.TicPaiement|.
I only want the lines that start with D between the previous strings.
W|301500120100407213036|
M|SYP||
T|DataObject.EShop.Tic.TicVente|
C|ArtId|ArtRef|PrxInit|QteArt|PrxEntId|TvaId|TvaTaux|RetourId|RetourMagAchat|RetourTicExtIdAchat|RetourDatAchat|PosteNum|TicId|LigNum|PrxAppel|PrxPaye|DatMaj|
D|18250168145|1825016814503131|1690|-1|0934489998|1|0|C|150||20100406000000|1|009700001|1|1690|1690|20100407093455|
D|18250137020|1825013702002161|750|1|1002689999|1|0|||||1|009700001|2|750|750|20100407093455|
D|18260013233|1826001323336111|1990|1|0935689998|1|0|||||1|009700002|1|1990|1990|20100407103918|
T|DataObject.EShop.Tic.TicPaiement|
C|PosteNum|TicId|LigNum|PaieId|Mnt|DevId|MntDev|Info1|Info2|TransId|TransOK|DatMaj|
D|1|009700001|1|01|-940|SYP|-940|||||20100407093455|
D|1|009700002|1|01|4000|SYP|4000|||||20100407103918|
T|DataObject.EShop.Tic.TicVenteAnnulee|
C|PosteNum|Dat|SessId|CliTypId|CliId|UtilId|LotId|ArtId|ArtRef|PrxInit|QteArt|PrxEntId|TvaId|TvaTaux|RetourId|RetourMagAchat|RetourTicExtIdAchat|RetourDatAchat|TicId|LigNum|PrxAppel|PrxPaye|DatMaj|
D|1|20100407105721|0097001|||6|0150010097763|18250040037|1825004003704121|990|1|1002689999|1|0|||||009700004|1|990|990|20100407213033|T|DataObject.EShop.Tic.TicVenteAnnulee|
C|PosteNum|Dat|SessId|CliTypId|CliId|UtilId|LotId|ArtId|ArtRef|PrxInit|QteArt|PrxEntId|TvaId|TvaTaux|RetourId|RetourMagAchat|RetourTicExtIdAchat|RetourDatAchat|TicId|LigNum|PrxAppel|PrxPaye|DatMaj|
D|1|20100407105721|0097001|||6|0150010097763|18250040037|1825004003704121|990|1|1002689999|1|0|||||009700004|1|990|990|20100407213033|
What about Regular Expressions?
You said:
starts in "T|DataObject.EShop.Tic.TicVente|" line
So it will begin with "^T|DataObject.EShop.Tic.TicVente|$"
You said:
T|DataObject.EShop.Tic.TicPaiement|
So it will end with "$T|DataObject.EShop.Tic.TicPaiement|$"
What else do you need? Each line starts with D? OK... try this
Regex rgx = new Regex("^T|DataObject.EShop.Tic.TicVente|$(D[.]*)$T|DataObject.EShop.Tic.TicPaiement|$", RegexOptions.MultiLine);
Or you can easily parse
set a flag indicating you are searching for your starting string
read lines until you find your start string (or EOF)
set a flag that indicates you are searching for the closing string
read lines until you find your ending string (or EOF)
when ending string found, set flag that
print all lines read between starting string and ending string
Well, you could find the first reference of T|DataObject, verify that it is the type you are looking for, then look for the next reference of T|DataObject.
Seems like it's just some simple string manipulation.
Is all of this on a single line or are the object header separated by carriage returns as well?
UPDATE
This is by no means the best way to do this and is just one possible way:
String sRecords = "T|DataObject.Test|C|RecordHeaderId|D|123|D|234|T|DataObject.Test2|C|RecordHeaderId|D|2345|D2366";
// this will split the string into an array on the boundary of |.
// which means you'll have all of item individual items separated out.
String[] sArray = sRecords.Split('|');
List<String> objects = new List<string>();
String obj = String.Empty;
foreach (String s in sArray) {
// locate the T item which defines a new record definition.
// the danger is if your data contains a "T" value somewhere it shouldn't
if (s.Equals("T") && !String.IsNullOrEmpty(obj)) {
objects.Add(obj);
obj = String.Empty;
}
obj = String.Format("{0}|{1}", obj, s);
}
objects.Add(obj);
// at this point "objects" hold a list of strings, each defined by the record type.
foreach (String s in objects) {
listBox1.Items.Add(s);
}

Loop Problem: Assign data to different strings when in a loop

I have a string which consists of different fields. So what I want to do is get the different text and assign each of them into a field.
ex: Hello Allan IBM
so what I want to do is:
put these three words in different strings like
string Greeting = "Hello"
string Name = "Allan"
string Company = "IBM"
//all of it happening in a loop.
string data = "Hello Allan IBM"
string s = data[i].ToString();
string[] words = s.Split(',');
foreach (string word in words) {
Console.WriteLine(word);
}
any suggestions?
thanks hope to hear from you soon
If I understand correctly you have a string with place-holders and you want to put different string in those place-holders:
var format="{0}, {1} {2}. How are you?";
//string Greeting = "Hello"
//string Name = "Allan"
//string Company = "IBM"
//all of it happening in a loop.
string data = ...; //I think you have an array of strings separated by ,
foreach( va s in data){
{
//string s = data[i];//.ToString(); - it is already a string array
string[] words = data[i].Split(',');
Console.WriteLine(format, words[0], words[1], words[2]);
}
To me it sound not like a problem that can be solved with a loop. The essential problem is that the loop can only work if you do exactly the same operation on the items within the loop. If your problem doesn't fit, you end up with a dozen of lines of code within the loop to handle special cases, what could have been written in a shorter way without a loop.
If there are only two or three strings you have to set (what should be the case if you have named variables), assign them from the indexes of the split string. An alternative would be using regular expressions to match some patterns to make it more robust, if one of the expected strings is missing.
Another possibility would be to set attributes on members or properties like:
[MyParseAttribute(/*position*/ /*regex*/)]
string Greeting {get;set;}
And use reflexion to populate them. Here you could create a loop on all properties having that attribute, as it sounds to me that you are eager to create a loop :-)

Categories

Resources