String manipulation to truncate string up to a specified expression on C# - c#

How do I remove more than three spaces from each line and end the string right there to look the line on the right using c#?
[Example1]
PO BOX XXX OVERDUE - PAY NOW
then transform to
PO BOX XXX
[Example2]
ClientB AMOUNT CARRI
then transform to
ClientB
[Example3]
PO BOX 400 FORWARD TO N
then transform to
PO BOX 400

var firstColumn = origString.SubString(0, origString.IndexOf(" "));

input = "PO BOX XXX OVERDUE - PAY NOW ";
input = input.Remove(input.IndexOf(" "));
there are 3 spaces in the indexOf paranthesis
Or you can do a split if you dont know if there is a tab or space -
input = input.Split(new char[] {' ', '\t'}, StringSplitOptions.RemoveEmptyEntries)[0];

You can do this:
var input = new string[3] { "PO BOX XXX OVERDUE - PAY NOW ",
"ClientB AMOUNT CARRI",
"PO BOX 400 FORWARD TO N "
};
for (int x = 0, len = input.Length; x != len; x++)
{
input[x] = Regex.Replace(input[x], #"\s{3}[^\n]+", string.Empty);
}
//input is ["PO BOX XXX","ClientB","PO BOX 400"]
Using linq:
var output = input.Select(str => Regex.Replace(str, #"\s{3}[^\r\n]+$", string.Empty));
if you're reading this string from file, you can do this:
var file = #"D:\file.txt";
var lines = File.ReadAllLines(file);
var output = lines.Select(str => Regex.Replace(str, #"\s{3}[^\n]+$", string.Empty)); // is ["PO BOX XXX","ClientB","PO BOX 400"]

You can use the string.Split method which results the string[]. Basing on the array count you can take the elements u need.
string base string = "PO BOX XXX OVERDUE - PAY NOW";
string[] delimittedStringArray = baseString.Split(' ');
if(delimittedStringArray.Length > 3)
{
// Take the data from array
}
else
{
// Do what ever
}
// I am not sure whether it is Length or Count in the if condition.

Related

How to combine two texts?

I have a Single line text box and Multiline text box, and want to include a word into the Single line text box with the words in Multiline text box per line
Like this :
Single line text: "Hello"(I have to use variables)<br>
Multiline words:
<br>
1998<br>
1999<br>
2000
Expected results:
Hello1998
Hello1999
Hello2000
Pls Help me
I use the below code, but it is not working just with the Single line text box and I have to manipulate by both text boxes:
string left = string.Format(add.Text , Environment.NewLine);
string right = string.Format(textBox1.Text, Environment.NewLine);
string[] leftSplit = left.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
string[] rightSplit = right.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
string output = "";
if (leftSplit.Length == rightSplit.Length)
{
for (int i = 0; i < leftSplit.Length; i++)
{
output += leftSplit[i] + ":" + rightSplit[i] + Environment.NewLine;
}
}
result.Text = output;
Could you please advise me on the right approach?
If you have single line only one word, then no need split it into an array.
Lets consider it as a string left = "Hello";
and textbox1 contains multiline words i.e.
string right = string.Format(textBox1.Text, Environment.NewLine); // right variable contains 1998 \n 1999 \n 2000
Then you can try below approach
var concatString = right.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(x => left + x);
string result = string.Join(Environment.NewLine , concatString);
.Net Fiddle
Output :
Hello1998
Hello1999
Hello2000
TextBox.GetLineText(int) will help you:
var singlelineText = singlelineTextBox.Text;
var composedLines = new List<string>();
for (var i = 0; i < multilineineTextBox.LineCount; i++)
{
composedLines.Add(singlelineText + multilineineTextBox.GetLineText(i));
}
result.Text = string.Join(EnvironmentNewline, composedLines);

C# compare input with keywords

ive got the following c# code:
string textBoxInput = richTextBox1.Text;
StreamReader SentencesFile = new StreamReader(#"C:\Users\Jeroen\Desktop\School\C#\opwegmetcsharp\answersSen.txt");
string Sentence = SentencesFile.ReadLine();
List<List<string>> keywordsList = new List<List<string>>();
List<string> outputSentence = new List<string>();
while (Sentence != null)
{
string keywords = Sentence.Substring(0, Sentence.IndexOf(' '));
string sentenceString = Sentence.Substring(0, Sentence.IndexOf(' ') +1);
List<string> splitKeyword = keywords.Split(',').ToList();
keywordsList.Add(splitKeyword);
outputSentence.Add(sentenceString);
}
int similar = 0;
int totalSimilar = 0;
List<string> SplitUserInput = textBoxInput.Split(' ').ToList();
And a .txt file which contains the following:
car,bmw Do you own a BMW?
car,Tesla Do you own a Tesla?
new,house Did you buy a new house?
snow,outside Is it snowing outside?
internet,down Is your internet down?
I can't figure out how i can compare every word that a user typed in the input (richTextBox1.Text) with the keywords in the .txt file ( like car and bmw for the first sentence )
And it also has to remember the sentence that has the highest amount of "hits".
I'm really stuck and searched a lot, but somehow i can't find out how i can do this.
A lot of thanks in advance!
You can use the LINQ Contains to check if a word is found in a list. But beware because it is case sensitive as password does. Use it like this:
//assuming you already list the keyword here
List<string> keywords = new List<string>() { "keyword1", "keyword2" };
Then for each sentence, supposing in this form:
string sentence1 = "Hi, this keYWord1 present! But quite malformed";
string sentence2 = "keywoRD2 and keyWOrd1 also present here, malformed";
Note: the above sentences could be your text from RichTextBox or file, it doesn't matter. Here I only show the concept.
You can do:
string[] words = sentence1.ToLower().Split(new char[] { ' ', ',', '.' });
int counter = 0;
for (int i = 0; i < words.Length; ++i){
counter += keywords.Contains(words[i]) ? 1 : 0;
}
And you can do likewise for sentence2. Whoever gets the highest counter has the highest hits.
This might be too advanced for a 1st year student but this piece of code will work for your need. Using Regex class to do matching for you. Performance-wise it's faster (AFAIK). I used a console application to work on this as I don't think it will be hard for you to use it in a WinForms/WPF application.
string textBoxInput = "car test do bmw"; // Just a sample as I am using a console app
string[] sentences = File.ReadAllLines("sentences.txt"); // Read all lines of a text file and assign it to a string array
string[] keywords = textBoxInput.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Split textBoxInput by space
int[] matchArray = new int[sentences.Length];
for(int i = 0; i < sentences.Length; i++)
{
Regex regex = new Regex(#"\b(" + string.Join("|", keywords.Select(Regex.Escape).ToArray()) + #"+\b)", RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(sentences[i]);
matchArray[i] = matches.Count;
}
int highesMatchIndex = Array.IndexOf(matchArray, matchArray.OrderByDescending(item => item).First());
Console.WriteLine("User input: " + textBoxInput);
Console.WriteLine("Matching sentence: " + sentences[highesMatchIndex]);
Console.WriteLine("Match count: " + matchArray[highesMatchIndex]);
Console.ReadLine();

Separate words from a string in C#

So i'm working on a program for a university degree. First requirement was to show the number of times each letter of the alphabet appears in a string. Now to develop this program further i would like to show all the words that are in the string, in a list. Here is the current code that i have.
public void occurances()
{
string sentence;
Console.WriteLine("\n");
Console.WriteLine("Please enter a random sentence and press enter");
Console.WriteLine("\n");
var occurances = new Dictionary<char, int>();
var words = occurances;
//a for each loop, and within it, the char variable is a assigned named "characters"
//The value "characters" will represent all the characters in the sentence string.
sentence = Console.ReadLine();
foreach (char characters in sentence)
{
//if the sentence contains characters
if (occurances.ContainsKey(characters))
//add 1 to the value of occurances
occurances[characters] = occurances[characters] + 1;
//otherwise keep the occurnaces value as 1
else
occurances[characters] = 1;
}
foreach (var entry in occurances)
{
//write onto the screen in position 0 and 1, where 0 will contain the entry key
// and 1 will contain the amount of times the entry has been entered
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
//Pause
Console.ReadLine();
}
For 1st Requirement:
var charGroups = sentence.GroupBy(x => x).OrderByDescending(x => x.Count());
For 2nd Requirement:
How to: Count Occurrences of a Word in a String (LINQ)
I thinks the easiest way would be this:
var WordList = YourString.Split(' ').toList(); // Making the list of words
var CharArray = YourString.toCharArray(); // Counting letters
var q = from x in CharArray
group x by x into g
let count = g.Count()
orderby count descending
select new {Value = g.Key, Count = count};

Cannot replace last element in string List

I have an input file that includes data on an entertainer and their performance score. For example,
1. Bill Monohan from North Town 10.54
2. Mary Greenberg from Ohio 3.87
3. Sean Hollen from Markell 7.22
I want to be able to take the last number from a line (their score), perform some math on it, and then replace the old score with the new score.
Here's a brief piece of code for what I'm trying to do:
string line;
StreamReader reader = new StreamReader(#"file.txt");
//Read each line and split by spaces into a List.
while ((line = reader.ReadLine())!= null){
//Find last item in List and convert to a Double in order to perform calculations.
List<string> l = new List<string>();
l = line.Split(null).ToList();
string lastItem = line.Split(null).Last();
Double newItem = Convert.ToDouble(lastItem);
/*Do some math*/
/*Replace lastItem with newItem*/
System.Console.WriteLine(line); }
When I write the new line, nothing changes but I want lastItem to be switched with newItem at the end of the line now. I've tried using:
l[l.Length - 1] = newItem.ToString();
But I'm getting no luck. I just need the best way to replace the last value of a string List like this. I've been going at this for a few hours now and I'm almost at the end of my rope.
Please help me c# masters!
You can use regular expression MatchEvaluator to get number from each line, do calculations, and replace original number with new one:
string line = "1. Bill Monohan from North Town 10.54";
line = Regex.Replace(line, #"(\d+\.?\d*)$", m => {
decimal value = Decimal.Parse(m.Groups[1].Value);
value = value * 2; // calculation
return value.ToString();
});
This regex captures decimal number at the end of input string. Output:
1. Bill Monohan from North Town 21.08
You're not changing anything to your line object before doing your WriteLine.
You will have to rebuild your line, something like this:
var items = string.Split();
items.Last() = "10";//Replace
var line = string.Join(" ", items)
Tip: strings are immutable, look it up.
This should work:
//var l = new List<string>(); // you don't need this
var l = line.Split(null).ToList();
var lastItem = l.Last(); // line.Split(null).Last(); don't split twice
var newItem = Convert.ToDouble(lastItem, CultureInfo.InvariantCulture);
/*Do some math*/
/*Replace lastItem with newItem*/
l[l.Count - 1] = newItem.ToString(); // change the last element
//Console.WriteLine(line); // line is the original string don't work
Console.WriteLine(string.Join(" ", l)); // create new string
This would probably do the job for you. A word on reading files though, if possible, ie they fit in memory, read the entire file at once, it gives you one disk access (well, depends on file size, but yeah) and you do not have to worry about filehandles.
// Read the stuff from the file, gets an string[]
var lines = File.ReadAllLines(#"file.txt");
foreach (var line in lines)
{
var splitLine = line.Split(' ');
var score = double.Parse(splitLine.Last(), CultureInfo.InvariantCulture);
// The math wizard is in town!
score = score + 3;
// Put it back
splitLine[splitLine.Count() - 1] = score.ToString();
// newLine is the new line, what should we do with it?
var newLine = string.Join(" ", splitLine);
// Lets print it cause we are out of ideas!
Console.WriteLine(newLine);
}
What do you want to do with the end result? Do you want it written back to file?
Try this
string subjectString = "Sean Hollen from Markell 7.22";
double Substring =double.Parse(subjectString.Substring(subjectString.IndexOf(Regex.Match(subjectString, #"\d+").Value), subjectString.Length - subjectString.IndexOf(Regex.Match(subjectString, #"\d+").Value)).ToString());
double NewVal = Substring * 10; // Or any of your operation
subjectString = subjectString.Replace(Substring.ToString(), NewVal.ToString());
Note: This will not work if the number appears twice on the same line
You are creating and initializing the list in a loop, hence it contains always only the current line. Do you want to find the highest score of all entertainers or the highest score of each entertainer (in case an entertainer could repeat in the file)?
However, here is an approach that gives you both:
var allWithScore = File.ReadAllLines(path)
.Select(l =>
{
var split = l.Split();
string entertainer = string.Join(" ", split.Skip(1).Take(split.Length - 2));
double score;
bool hasScore = double.TryParse(split.Last(), NumberStyles.Float, CultureInfo.InvariantCulture, out score);
return new { line = l, split, entertainer, hasScore, score };
})
.Where(x => x.hasScore);
// highest score of all:
double highestScore = allWithScore.Max(x => x.score);
// entertainer with highest score
var entertainerWithHighestScore = allWithScore
.OrderByDescending(x => x.score)
.GroupBy(x => x.entertainer)
.First();
foreach (var x in entertainerWithHighestScore)
Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);
// all entertainer's highest scores:
var allEntertainersHighestScore = allWithScore
.GroupBy(x => x.entertainer)
.Select(g => g.OrderByDescending(x => x.score).First());
foreach (var x in allEntertainersHighestScore)
Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);

Extracting parts of a string c#

In C# what would be the best way of splitting this sort of string?
%%x%%a,b,c,d
So that I end up with the value between the %% AND another variable containing everything right of the second %%
i.e. var x = "x"; var y = "a,b,c,d"
Where a,b,c.. could be an infinite comma seperated list. I need to extract the list and the value between the two double-percentage signs.
(To combat the infinite part, I thought perhaps seperating the string out to: %%x%% and a,b,c,d. At this point I can just use something like this to get X.
var tag = "%%";
var startTag = tag;
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(tag, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
Would the best approach be to use regex or use lots of indexOf and substring to do the extracting based on te static %% characters?
Given that what you want is "x,a,b,c,d" the Split() function is actually pretty powerful and regex would be overkill for this.
Here's an example:
string test = "%%x%%a,b,c,d";
string[] result = test.Split(new char[] { '%', ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in result) {
Console.WriteLine(s);
}
Basicly we ask it to split by both '%' and ',' and ignore empty results (eg. the result between "%%"). Here's the result:
x
a
b
c
d
To Extract X:
If %% is always at the start then;
string s = "%%x%%a,b,c,d,h";
s = s.Substring(2,s.LastIndexOf("%%")-2);
//Console.WriteLine(s);
Else;
string s = "v,u,m,n,%%x%%a,b,c,d,h";
s = s.Substring(s.IndexOf("%%")+2,s.LastIndexOf("%%")-s.IndexOf("%%")-2);
//Console.WriteLine(s);
If you need to get them all at once then use this;
string s = "m,n,%%x%%a,b,c,d";
var myList = s.ToArray()
.Where(c=> (c != '%' && c!=','))
.Select(c=>c).ToList();
This'll let you do it all in one go:
string pattern = "^%%(.+?)%%(?:(.+?)(?:,|$))*$";
string input = "%%x%%a,b,c,d";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
// "x"
string first = match.Groups[1].Value;
// { "a", "b", "c", "d" }
string[] repeated = match.Groups[2].Captures.Cast<Capture>()
.Select(c => c.Value).ToArray();
}
You can use the char.IsLetter to get all the list of letter
string test = "%%x%%a,b,c,d";
var l = test.Where(c => char.IsLetter(c)).ToArray();
var output = string.Join(", ", l.OrderBy(c => c));
Since you want the value between the %% and everything after in separate variables and you don't need to parse the CSV, I think a RegEx solution would be your best choice.
var inputString = #"%%x%%a,b,c,d";
var regExPattern = #"^%%(?<x>.+)%%(?<csv>.+)$";
var match = Regex.Match(inputString, regExPattern);
foreach (var item in match.Groups)
{
Console.WriteLine(item);
}
The pattern has 2 named groups called x and csv, so rather than just looping, you can easily reference them by name and assign them to values:
var x = match.Groups["x"];
var y = match.Groups["csv"];

Categories