Auto-numbering each line in textbox - c#

I want to auto number each line that a user puts into a textbox and display the result in another textbox.
Turn this
blah blah blah
some stuff to be numbered
more stuff to number
to this
1 blah blah blah
2 some stuff to be numbered
3 more stuff to number
so far I have
output.Text = Regex.Replace(input.Text, input.Text, #"{1,}+");
But this is replacing all text with {1,}
I cant seem to figure out how to loop each line back after placing a number and a space.
(I am new to c#)
Any suggestions?

It might be simpler to implement a non-Regex solution:
var numberedLines = input.Text
.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None)
.Select ((line, index) => (index + 1) + " " + line)
.ToArray();
var result = string.Join(Environment.NewLine, numberedLines);
output.Text = result;
The first line uses string.Split() to split up the string around line returns into an array. Then I use LINQ .Select method to apply a function to each element in the array - in this case, adding line number and space at the beginning of each line (index + 1 is necessary because the index values are 0-based). Then I use string.Join method to put the array back together into a single string.
Demo: http://ideone.com/DrFTfl
It can actually be done with a Regular Expression if you use a MatchEvaluator delegate to apply the line numbering:
var index = 1;
output.Text = Regex.Replace(input.Text, "^",
(Match m) => (index++).ToString() + " ",
RegexOptions.Multiline);
The pattern ^ typically matches the beginning of an expression. However, with RegexOptions.Multiline, it matches the beginning of each line. Then for replacement, I use a delegate (anonymous function) that adds # + space to the beginning of the line, and then increments the index counter for the next row.
Demo: http://ideone.com/9LD0ZY

Why not just split by \r\n, concatenate each line of the string[] with an incremented number and a space, and then join by \r\n ?

If you're new to C# lets keep it as simple as possible.
By the looks of it you already have all your strings. So it boils down to this:
// store all lines in a list
// ...
var list = new List<string> {"blah", "blah2", "and some more blah"};
var list2 = new List<string>();
var i = 1;
foreach (var str in list)
{
list2.Add(string.Format("{0} {1}", i, str));
i++;
}
// write contents of list2 back to wherever you want them visualized

Related

Taking parts out of a string, how?

So I have a server that receives a connection with the message being converted to a string, I then have this string split between by the spaces
So you have a line:
var line = "hello world my name is bob";
And you don't want "world" or "is", so you want:
"hello my name bob"
If you split to a list, remove the things you don't want and recombine to a line, you won't have extraneous spaces:
var list = line.Split().ToList();
list.Remove("world");
list.Remove("is");
var result = string.Join(" ", list);
Or if you know the exact index positions of your list items, you can use RemoveAt, but remove them in order from highest index to lowest, because if you e.g. want to remove 1 and 4, removing 1 first will mean that the 4 you wanted to remove is now in index 3.. Example:
var list = line.Split().ToList();
list.RemoveAt(4); //is
list.RemoveAt(1); //world
var result = string.Join(" ", list);
If you're seeking a behavior that is like string.Replace, which removes all occurrences, you can use RemoveAll:
var line = "hello is world is my is name is bob";
var list = line.Split().ToList();
list.RemoveAll(w => w == "is"); //every occurence of "is"
var result = string.Join(" ", list);
You could remove the empty space using TrimStart() method.
Something like this:
string text = "Hello World";
string[] textSplited = text.Split(' ');
string result = text.Replace(textSplited[0], "").TrimStart();
Assuming that you only want to remove the first word and not all repeats of it, a much more efficient way is to use the overload of split that lets you control the maximum number of splits (the argument is the maximum number of results, which is one more than the maximum number of splits):
string[] arguments = line.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); // split only once
User.data = arguments.Skip(1).FirstOrDefault();
arguments[1] does the right thing when there are "more" arguments, but throw IndexOutOfRangeException if the number of words is zero or one. That could be fixed without LINQ by (arguments.Length > 1)? arguments[1]: string.Empty
If you're just removing the first word of a string, you don't need to use Split at all; doing a Substring after you found the space will be more efficient.
var line = ...
var idx = line.IndexOf(' ')+1;
line = line.Substring(idx);
or in recent C# versions
line = line[idx..];

How to split lines but keep those with tabs?

I know how to split a long string by new lines
string[] lines = d.Split(new string[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries);
But I would like to
Split in new lines like this
and in new lines + tabs
like this, in order to have
an array which contains the first line and this second block.
Basically I would like to split not by one rule, but by two.
The resulting array should contain following strings:
[0] Split in new lines like this
[1] and in new lines + tabs
like this, in order to have
an array which contains the first line and this second block.
This trick should work. I have replaced "\n\t" with "\r" temporarily. After splitting the string, restored back the "\n\t" string. So your array lines, will have desired count of strings.
This way, you can get your desired output:
d = d.Replace("\n\t", "\r");
string[] lines = d.Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries);
lines = lines.Select((line) => line = line.Replace("\r", "\n\t")).ToArray();
What is a tab?
If it is 4 spaces, use the following pattern:
string pattern = Environment.NewLine + #"(?!\s{4})";
If it is tabulation, use the following pattern:
string pattern = Environment.NewLine + #"(?!\t)";
Next, we use a regular expression:
string[] lines = Regex.Split(text, pattern);
One should use the right tool for the right situation. To avoid using a tool available to one (a tool which is in every programming language btw) is foolish.
Regex is best when a discernible pattern has to be expressed which can't be done, or easily done, by the string functions. Below I use each tool in the situation it was best designed for...
The following is a three stage operation using regex, string op, and Linq.
Identifying which lines have to be kept together due to the indented rule. This is done to not lose them in the main split operation, the operation will replace \r\n\t with a pipe character (|) to identify their specialty. This is done with regex because we are able to effectively group and process the operations with minimal overhead.
We split all the remaining lines by the newline character which gives us a glimpse at the final array of lines wanted.
We project (change) each line via linq's Select to change the | to a \r\n.
Code
Regex.Replace(text, "\r\n\t", "|\t")
.Split(new string[] { Environment.NewLine }, StringSplitOptions.None )
.Select (rLine => rLine.Replace("|", Environment.NewLine));
Try it here (.Net Fiddle)
Full code with before and after results as run in LinqPad. Note that .Dump() is only available in Linqpad to show results and is not a Linq extension.
Result first:
Full code
string text = string.Format("{1}{0}{2}{0}\t\t{3}{0}\t\t{4}",
Environment.NewLine,
"Split in new lines like this",
"and in new lines + tabs",
"like this, in order to have",
"an array which contains the first line and this second block.");
text.Dump("Before");
var result = Regex.Replace(text, "\r\n\t", "|\t")
.Split(new string[] { Environment.NewLine }, StringSplitOptions.None )
.Select (rLine => rLine.Replace("|", Environment.NewLine));
result.Dump("after");
After you split all lines, you can just "join" tabbed lines like so:
List<string> lines = d.Split(new string[] { Environment.NewLine })
.ToList();
// loop through all lines, but skip the first (lets assume it isn't tabbed)
for (int i = 1; i < lines.Count; i++)
{
if (lines[i][0] == '\t') // current line starts with tab
{
lines[i - 1] += "\r\n" + lines[i]; // append it to prev line
lines.RemoveAt(i); // remove current line from list
i--; // and dec i so you don't skip an item
}
}
You could add more complex logic to consider different number of tabs if you wanted, but this should get you started.
If you expect many tabbed lines to be grouped together, you might want to use StringBuilder instead of string for increased performance in appending the lines back together.

Split and add specific charcters to a string in C#

I am working with key-wording modules where each word end with , and remove spaces from the string example is given below:
if string is
one man sitting with girl , baby girl , Smiling girl
then result should be
,one man sitting with girl,baby girl,Smiling girl,
I am trying this
string[] strArray = str15.Split(new char[] { ',', ';' });
if (strArray.Length >= 1)
{
foreach (string str3 in strArray)
{
if (str3 != string.Empty)
{
strr1 = strr1 + str3 + ",";
}
}
}
But not able to remove spaces from string.
The first thing you want to do is tokenise the string, using Split().
string input = "some words , not split , in a sensible , way";
string[] sections = input.Split(',');
This gives you an array of strings split by the comma delimiter, which would look something like this:
"some words "
" not split "
" in a sensible "
" way"
Now you want to trim those spaces off. The string class has a great little function called Trim() which removes all whitespace characters (spaces, tabs, etc) from the start and end of strings.
for (int i = 0; i < sections.Length; i++)
sections[i] = sections[i].Trim();
Now you have an array with strings like this:
"some words"
"not split"
"in a sensible"
"way"
Next, you want to join them back together with a comma delimiter.
string result = string.Join(",", sections);
This gives you something along the lines of this:
"some words,not split,in a sensible,way"
And finally, you can add the commas at the start and end:
result = "," + result + ",";
Of course, this isn't the cleanest way of doing it. It's just an easy way of describing the individual steps. You can combine all of this together using LINQ extensions:
string result = "," + string.Join(",", input.Split(',').Select(s => s.Trim())) + ",";
This takes the input, splits it on the comma delimiter, then for each item in the list executes a lambda expression s => s.Trim(), which selects the trimmed version of the string for each element. This resulting enumerable is then passed back into string.Join(), and then we add the two commas at the start and end. It has the same function as the above steps, but does it one line.
Try this:
var input = "one man sitting with girl , baby girl , Smiling girl";
var output = string.Join(",", input.Split(',').Select(x => x.Trim()));
output = string.Concat(",", output, ",");
This should work:
string test = "one man sitting with girl , baby girl , Smiling girl";
Regex regex = new Regex(#"\s+,\s+");
string result = regex.Replace(test, ",");
Split your string and join it again by removing the white-spaces:
var input = "one man sitting with girl , baby girl , Smiling girl";
var output = string.Join(",", input.Split(',').Select(x => x.Trim()));
// If you wanna enclose it with commas
output = string.Format(",{0},",output);

How do I know which delimiter was used when delimiting a string on multiple delimiters? (C#)

I read strings from a file and they come in various styles:
item0 item1 item2
item0,item1,item2
item0_item1_item2
I split them like this:
string[] split_line = line[i].split(new char[] {' ',',','_'});
I change an item (column) and then i stitch the strings back together using string builder.
But now when putting the string back I have to use the right delimiter.
Is it possible to know which delimiter was used when splitting the string?
UPDATE
the caller will pass me the first item so that I only change that line.
Unless you keep track of splitting action (one at the time) you don't.
Otherwise, you could create a regular expression, to catch the item and the delimiter and go from there.
Instead of passing in an array of characters, you can use a Regex to split the string instead. The advantage of doing this, is that you can capture the splitting character. Regex.Split will insert any captures between elements in the array like so:
string[] space = Regex.Split("123 456 789", #"([,_ ])");
// Results in { "123", " ", "456", " ", "789" }
string[] comma = Regex.Split("123,456,789", #"([,_ ])");
// Results in { "123", ",", "456", ",", "789" }
string[] underscore = Regex.Split("123_456_789", #"([,_ ])");
// Results in { "123", "_", "456", "_", "789" }
Then you can edit all items in the array with something like
for (int x = 0; x < space.Length; x += 2)
space[x] = space[x] + "x";
Console.WriteLine(String.Join("", space));
// Will print: 123x 456x 789x
One thing to be wary of when dealing with multiple separators is if there are any lines that have spaces, commas and underscores in them. e.g.
37,hello world,238_3
This code will preserve all the distinct separators but your results might not be expected. e.g. the output of the above would be:
37x,hellox worldx,238x_3x
As I mentioned that the caller passes me the first item so I tried something like this:
// find the right row
if (lines[i].ToLower().StartsWith(rowID))
{
// we have to know which delim was used to split the string since this will be
// used when stitching back the string together.
for (int delim = 0; delim < delims.Length; delim++)
{
// we split the line into an array and then use the array index as our column index
split_line = lines[i].Trim().Split(delims[delim]);
// we found the right delim
if (split_line.Length > 1)
{
delim_used = delims[delim];
break;
}
}
}
basically I iterate each line over the delims and check the resulting array length. If it is > 1 that means that delim worked otherwise skip to next one. I am using split functions property "If this instance does not contain any of the characters in separator, the returned array consists of a single element that contains this instance."

Go to each white space in a string. C#

Is it possible to pass over a string, finding the white spaces?
For example a data set of:
string myString = "aa bbb cccc dd";
How could I loop through and detect each white space, and manipulate that space?
I need to do this in the most effecient way possible.
Thanks.
UPDATE:
I need to manipulate the space by increasing the white space from an integer value. So for instance increase the space to have 3 white spaces instead of one. I'd like to make it go through each white space in one loop, any method of doing this already in .NET? By white space I mean a ' '.
You can use the Regex.Replace method. This will replace any group of white space character with a dash:
myString = Regex.Replace(myString, "(\s+)", m => "-");
Update:
This will find groups of space characters and replace with the tripple amount of spaces:
myString = Regex.Replace(
myString,
"( +)",
m => new String(' ', m.Groups[1].Value.Length * 3)
);
However, that's a bit too simple to make use of regular expressions. You can do the same with a regular replace:
myString = myString.Replace(" ", " ");
This will replace each space intead of replace groups of spaces, but the regular replace is much simpler than Regex.Replace, so it should still be at least as fast, and the code is simpler.
If you want to replace all whitespace in one swoop, you can do:
// changes all strings to dashes
myString.Replace(' ', '-');
If you want to go case by case (that is, not just a mass replace), you can loop through IndexOf():
int pos = myString.IndexOf(' ');
while (pos >= 0)
{
// do whatever you want with myString # pos
// find next
pos = myString.IndexOf(' ', pos + 1);
}
UPDATE
As per your update, you could replace single spaces with the number of spaces specified by a variable (such as numSpaces) as follows:
myString.Replace(" ", new String(' ', numSpaces));
If you just want to replace all spaces with some other character:
myString = myString.Replace(' ', 'x');
If you need the possibility of doing something different to each:
foreach(char c in myString)
{
if (c == ' ')
{
// do something
}
}
Edit:
Per your comment clarifying your question:
To change each space to three spaces, you can do this:
myString = myString.Replace(" ", " ");
However note that this doesn't take into account instances where your input string already has two or more spaces. If that is a possibility you will want to use a regex.
Depending on what you're tring to do:
for(int k = 0; k < myString.Length; k++)
{
if(myString[k].IsWhiteSpace())
{
// do something with it
}
}
The above is a single pass through the string, so it's O(n). You can't really get more efficient that that.
However, if you want to manipulate the original string your best bet is to Use a StringBuilder to process the changes:
StringBuilder sb = new StringBuilder(myString);
for(int k = 0; k < myString.Length; k++)
{
if(myString[k].IsWhiteSpace())
{
// do something with sb
}
}
Finally, don't forget about Regular Expressions. It may not always be the most efficient method in terms of code run-time complexity but as far as efficiency of coding it may be a good trade-off.
For instance, here's a way to match all white spaces:
var rex = new System.Text.RegularExpressions.Regex("[^\\s](\\s+)[^\\s]");
var m = rex.Match(myString);
while(m.Success)
{
// process the match here..
m.NextMatch();
}
And here's a way to replace all white spaces with an arbitrary string:
var rex = new System.Text.RegularExpressions.Regex("\\s+");
String replacement = "[white_space]";
// replaces all occurrences of white space with the string [white_space]
String result = rex.Replace(myString, replacement);
Use string.Replace().
string newString = myString.Replace(" ", " ");
LINQ query below returns a set of anonymous type items with two properties - "sybmol" represents a white space character, and "index" - index in the input sequence. After that you have all whitespace characters and a position in the input sequence, now you can do what you want with this.
string myString = "aa bbb cccc dd";
var res = myString.Select((c, i) => new { symbol = c, index = i })
.Where(c => Char.IsWhiteSpace(c.symbol));
EDIT: For educational purposes below is implementation you are looking for, but obviously in real system use built in string constructor and String.Replace() as shown in other answers
string myString = "aa bbb cccc dd";
var result = this.GetCharacters(myString, 5);
string output = new string(result.ToArray());
public IEnumerable<char> GetCharacters(string input, int coeff)
{
foreach (char c in input)
{
if (Char.IsWhiteSpace(c))
{
int counter = coeff;
while (counter-- > 0)
{
yield return c;
}
}
else
{
yield return c;
}
}
}
var result = new StringBuilder();
foreach(Char c in myString)
{
if (Char.IsWhiteSpace(c))
{
// you can do what you wish here. strings are immutable, so you can only make a copy with the results you want... hence the "result" var.
result.Append('_'); // for example, replace space with _
}
else result.Append(c);
}
myString = result.ToString();
If you want to replace the white space with, e.g. '_', you can using String.Replace.
Example:
string myString = "aa bbb cccc dd";
string newString = myString.Replace(" ", "_"); // gives aa_bbb_cccc_dd
In case you want to left/right justify your string
int N=10;
string newstring = String.Join(
"",
myString.Split(' ').Select(s=>s.PadRight(N-s.Length)));

Categories

Resources