I have a list of names and I loop through them to create a comma separated list in a string variable (Bob, George, Will, Terry).
I need the list to eventually look like (Bob, George, Will and Terry).
How do I find the LAST instance of the comma and replace it with the word "and"? Once I find the LAST instance, I think it's a simple matter of doing something like
string new=ori.Substring(0,start) + rep + ori.Substring(start+rep.Length);
Thoughts? Comments? Suggestions?
Thanks,
Bob
This should work for you. Added the alternative comma style as well.
var names = "Bob, George, Will, Terry";
var lastCommaPosition = names.LastIndexOf(',');
if (lastCommaPosition != -1)
{
names = names.Remove(lastCommaPosition, 1)
//.Insert(lastComma, " and");
.Insert(lastCommaPosition, ", and");
}
Console.WriteLine(names);
You can use a combination of LINQ and String.Join. This solution does not need the last index of a comma and is "more fluent" to read.
var list = new List<string> { "Bob", "George", "Will", "Terry" };
var listAsString = list.Count > 1
? string.Join(", ", list.Take(list.Count - 1)) + " and " + list.Last()
: list.First();
You can use Linq,
list.Select(i => i).Aggregate((i, j) => i + (list.IndexOf(j) == list.Count -1 ? " and " : " , ") + j);
Hope helps,
This should do the trick for you:
var foo = "Bob, George, Will, Terry";
if (foo.Contains(",")) {
foo = foo.Substring(0, foo.LastIndexOf(",")) + " and" + foo.Substring(foo.LastIndexOf(",")+ 1);
}
I'm not sure what you wanted to do, but the following code works:
string original = "(Bob, George, Will, Terry)";
string result = "";
string[] splited = original.Split(',');
for (int i = 0; i < splited.Count(); i++)
{
if(i == splited.Count() - 2)
{
result += splited[i] + " and";
}
else if(i == splited.Count() - 1)
{
result += splited[i];
}
else
{
result += splited[i] + ",";
}
}
I Used split to split the original string in a vector so i worked with this vector to replace the last comma to the word "and".
I have this string:
string myString = "do Output.printString(\"Do you want to Hit (h) or Stand (s)?\");";
My string as plain text:
do Output.printString("Do you want to Hit (h) or Stand (s)?");
I want to make it:
do Output . printString ("Do#you#want#to Hit#(h)#or#Stand#(s)?");
The idea is that there is a space between each word but if there is a string within apostrophes I want it to be WITHOUT SPACE and after this function I can do:
s.Split(' ');
and get the string in one string.
What I did is:
public static string PrepareForSplit(this string s)
{
string ret = "";
if (s.Contains("\""))
{
bool equalsAppear = false;
foreach (var nextChar in s)
{
char charToConcat;
if (nextChar == '"')
{
equalsAppear= equalsAppear == true ? false : true;
}
if (nextChar == ' ' && equalsAppear)
{
charToConcat = '#';
}
else
{
charToConcat = nextChar;
}
ret += charToConcat;
}
}
if (String.IsNullOrWhiteSpace(ret))
ret = s;
string[] symbols = {"{", "}", "(", ")", "[", "]", ".",
",", ";", "+", "-", "*", "/", "&", "|", "<", ">", "=", "~","#"};
foreach(var symbol in symbols)
if(ret.Contains(symbol))
{
if (!ret.Contains('"') || !((symbol=="-") || symbol==","))
{
ret = ret.Replace(symbol, " " + symbol + " ");
}
}
if(ret.Contains("\t"))
{
ret = Regex.Replace(ret, #"\t", " ");
}
return ret;
}
My problem is that in the end of this function I get this string:
do Output . printString ( "Do#you#want#to#Hit# ( h ) #or#Stand# ( s ) ?" ) ;
As you can see in the string that suppose to be without spacing I have spaces and then my program not behave as it should. Someone please help!
I would use a regular expression to extract your string.
You probably enter the starting string like this:
string source = "do Output.printString(\"Do you want to Hit (h) or Stand (s)?\");";
Try this regular expression:
\("([^\"]+)
The group between round brackets (i.e. the capturing group) is what you're looking for.
Edit: use it like this (based on http://www.dotnetperls.com/regex-match)
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
// First we see the input string.
string source = "do Output.printString(\"Do you want to Hit (h) or Stand (s)?\");";
// Here we call Regex.Match.
Match match = Regex.Match(source, "\\(\"([^\"]+)");
// Here we check the Match instance.
if (match.Success)
{
// Finally, we get the Group value and display it.
string key = match.Groups[1].Value;
Console.WriteLine("result: "+ key);
}
else
{
Console.WriteLine("nothing found");
}
Console.ReadLine();
}
}
Edit2: now it works :-)
I suggest you to split the whole string at the apostrophes. This will make it much easier to differentiate between parts that are within apostrophes and the others.
string[] parts = s.Split('"');
Now you have:
part[0] ==> "do Output . printString ("
part[1] ==> "Do#you#want#to Hit#(h)#or#Stand#(s)?"
part[2] ==> ");"
I.e., the even indexes in part[] are outside the apostrophes, the odd indexes are within.
// Treat the parts not between apostrophes:
for (int i = 0; i < parts.Length; i += 2) {
part[i] = InsertSpacesBetweenWords(part[i]);
}
string result = String.Join("\"", part);
By the way: In your example, you can simplify
equalsAppear = equalsAppear == true ? false : true;
to
equalsAppear = !equalsAppear;
by using the logical NOT operator !.
Hello im a bit stuck i dont know how to find the third longest word in a string, i have got my code to find the longest but i cant manage to get it to find the third longest. any help?
public void longestWord()
{
string sentance, word;
word = " ";
char[] a = new char[] { ' ' };
sentance = textBox1.Text; //<--string here
foreach (string s1 in sentance.Split(a))
{
if (word.Length < s1.Length)
{
word = s1;
}
}
label9.Text = ("The longest word is " + word + " and its length is " + word.Length + " characters long");
}
P.S an example of the string im testing is:
1.
DarkN3ss is my most experienced provider of Windows based business solutions. I focus on delivering my business value in best possible understanding of this technologies and directions.
DarkN3ss recognising me as an “elite business partner” for implementing solutions based on my capabilities and experience with Windows and Linux products.
how about using linq?
sentance.Split(' ').OrderByDescending(w => w.Length).Skip(2).FirstOrDefault()
in a function :
public void nthLongestWord(int index = 0)
{
string word = null;
if(index <= 0)
{
word = sentance.Split(' ').OrderByDescending(w => w.Length).FirstOrDefault();
}
else
{
word = sentance.Split(' ').OrderByDescending(w => w.Length).Skip(index - 1).FirstOrDefault();
}
if(!string.IsNullOrWhitespace(word))
{
label9.Text = ("The longest word is " + word + " and its length is " + word.Length + " characters long");
}
else
{
// display something else?
}
}
Solution: To get all the third largest words
string[] splitStr = sentence.Split(' ');
if (splitStr.Length > 2)
{
List<int> allLengths = splitStr.Select(x => x.Length).Distinct().ToList();
int thirdLargestWordLength = allLengths.OrderByDescending(x => x)
.Skip(2).Distinct().Take(1).FirstOrDefault();
if (splitStr[0].Length != thirdLargestWordLength &&
splitStr[1].Length != thirdLargestWordLength)
{
string[] theThirdLargestWords = splitStr.Where(x => x.Length == thirdLargestWordLength)
.ToArray();
if (theThirdLargestWords.Length == 1)
{
label9.Text = "The third longest word is " + theThirdLargestWords[0];
}
else
{
string words = "";
for (int i = 0; i < theThirdLargestWords.Length; i++)
{
if (i == 0)
{
words = theThirdLargestWords[i];
}
//else if ((i + 1) == theThirdLargestWords.Length)
//{
// words += " and " + theThirdLargestWords[i];
//}
else
{
words += ", " + theThirdLargestWords[i];
}
}
label9.Text = "The third longest words are " + words;
}
}
}
I commented out the "and" part as i'm not sure if you want that in your string. I also added the first if statement so you don't get an error if you have less then 3 words.
If you'd like to make minimal changes to your current code, then what you should do is store the three longest words (i.e., instead of word, have word1, word2, and word3, or an array if you'd prefer).
Then, in your if statement, set word3=word2, word2=word1, and word1=s1.
That way, the third largest word will end up in word3.
Not the most efficient, but you'll be able to keep your current code, to a degree.
If you feel confortable using a temporary array, you should copy your words there, sort them and take the 3rd longest one.
This might have compile error, but just to give you an idea.
var words = sentence.split();
words.OrderBy (w => w.length ).ToArray ()[2]
How can I replace multiple spaces in a string with only one space in C#?
Example:
1 2 3 4 5
would be:
1 2 3 4 5
I like to use:
myString = Regex.Replace(myString, #"\s+", " ");
Since it will catch runs of any kind of whitespace (e.g. tabs, newlines, etc.) and replace them with a single space.
string sentence = "This is a sentence with multiple spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
sentence = regex.Replace(sentence, " ");
string xyz = "1 2 3 4 5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
I think Matt's answer is the best, but I don't believe it's quite right. If you want to replace newlines, you must use:
myString = Regex.Replace(myString, #"\s+", " ", RegexOptions.Multiline);
Another approach which uses LINQ:
var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
str = string.Join(" ", list);
It's much simpler than all that:
while(str.Contains(" ")) str = str.Replace(" ", " ");
Regex can be rather slow even with simple tasks. This creates an extension method that can be used off of any string.
public static class StringExtension
{
public static String ReduceWhitespace(this String value)
{
var newString = new StringBuilder();
bool previousIsWhitespace = false;
for (int i = 0; i < value.Length; i++)
{
if (Char.IsWhiteSpace(value[i]))
{
if (previousIsWhitespace)
{
continue;
}
previousIsWhitespace = true;
}
else
{
previousIsWhitespace = false;
}
newString.Append(value[i]);
}
return newString.ToString();
}
}
It would be used as such:
string testValue = "This contains too much whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."
myString = Regex.Replace(myString, " {2,}", " ");
For those, who don't like Regex, here is a method that uses the StringBuilder:
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i == 0 || c != ' ' || (c == ' ' && input[i - 1] != ' '))
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
In my tests, this method was 16 times faster on average with a very large set of small-to-medium sized strings, compared to a static compiled Regex. Compared to a non-compiled or non-static Regex, this should be even faster.
Keep in mind, that it does not remove leading or trailing spaces, only multiple occurrences of such.
This is a shorter version, which should only be used if you are only doing this once, as it creates a new instance of the Regex class every time it is called.
temp = new Regex(" {2,}").Replace(temp, " ");
If you are not too acquainted with regular expressions, here's a short explanation:
The {2,} makes the regex search for the character preceding it, and finds substrings between 2 and unlimited times.
The .Replace(temp, " ") replaces all matches in the string temp with a space.
If you want to use this multiple times, here is a better option, as it creates the regex IL at compile time:
Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");
You can simply do this in one line solution!
string s = "welcome to london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");
You can choose other brackets (or even other characters) if you like.
no Regex, no Linq... removes leading and trailing spaces as well as reducing any embedded multiple space segments to one space
string myString = " 0 1 2 3 4 5 ";
myString = string.Join(" ", myString.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
result:"0 1 2 3 4 5"
// Mysample string
string str ="hi you are a demo";
//Split the words based on white sapce
var demo= str .Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
//Join the values back and add a single space in between
str = string.Join(" ", demo);
// output: string str ="hi you are a demo";
Consolodating other answers, per Joel, and hopefully improving slightly as I go:
You can do this with Regex.Replace():
string s = Regex.Replace (
" 1 2 4 5",
#"[ ]{2,}",
" "
);
Or with String.Split():
static class StringExtensions
{
public static string Join(this IList<string> value, string separator)
{
return string.Join(separator, value.ToArray());
}
}
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
I just wrote a new Join that I like, so I thought I'd re-answer, with it:
public static string Join<T>(this IEnumerable<T> source, string separator)
{
return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}
One of the cool things about this is that it work with collections that aren't strings, by calling ToString() on the elements. Usage is still the same:
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
Many answers are providing the right output but for those looking for the best performances, I did improve Nolanar's answer (which was the best answer for performance) by about 10%.
public static string MergeSpaces(this string str)
{
if (str == null)
{
return null;
}
else
{
StringBuilder stringBuilder = new StringBuilder(str.Length);
int i = 0;
foreach (char c in str)
{
if (c != ' ' || i == 0 || str[i - 1] != ' ')
stringBuilder.Append(c);
i++;
}
return stringBuilder.ToString();
}
}
Use the regex pattern
[ ]+ #only space
var text = Regex.Replace(inputString, #"[ ]+", " ");
I know this is pretty old, but ran across this while trying to accomplish almost the same thing. Found this solution in RegEx Buddy. This pattern will replace all double spaces with single spaces and also trim leading and trailing spaces.
pattern: (?m:^ +| +$|( ){2,})
replacement: $1
Its a little difficult to read since we're dealing with empty space, so here it is again with the "spaces" replaced with a "_".
pattern: (?m:^_+|_+$|(_){2,}) <-- don't use this, just for illustration.
The "(?m:" construct enables the "multi-line" option. I generally like to include whatever options I can within the pattern itself so it is more self contained.
I can remove whitespaces with this
while word.contains(" ") //double space
word = word.Replace(" "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.
Without using regular expressions:
while (myString.IndexOf(" ", StringComparison.CurrentCulture) != -1)
{
myString = myString.Replace(" ", " ");
}
OK to use on short strings, but will perform badly on long strings with lots of spaces.
try this method
private string removeNestedWhitespaces(char[] st)
{
StringBuilder sb = new StringBuilder();
int indx = 0, length = st.Length;
while (indx < length)
{
sb.Append(st[indx]);
indx++;
while (indx < length && st[indx] == ' ')
indx++;
if(sb.Length > 1 && sb[0] != ' ')
sb.Append(' ');
}
return sb.ToString();
}
use it like this:
string test = removeNestedWhitespaces("1 2 3 4 5".toCharArray());
Here is a slight modification on Nolonar original answer.
Checking if the character is not just a space, but any whitespace, use this:
It will replace any multiple whitespace character with a single space.
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
var stringBuilder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) &&
!char.IsWhiteSpace(strValue[i - 1])))
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
How about going rogue?
public static string MinimizeWhiteSpace(
this string _this)
{
if (_this != null)
{
var returned = new StringBuilder();
var inWhiteSpace = false;
var length = _this.Length;
for (int i = 0; i < length; i++)
{
var character = _this[i];
if (char.IsWhiteSpace(character))
{
if (!inWhiteSpace)
{
inWhiteSpace = true;
returned.Append(' ');
}
}
else
{
inWhiteSpace = false;
returned.Append(character);
}
}
return returned.ToString();
}
else
{
return null;
}
}
Mix of StringBuilder and Enumerable.Aggregate() as extension method for strings:
using System;
using System.Linq;
using System.Text;
public static class StringExtension
{
public static string CondenseSpaces(this string s)
{
return s.Aggregate(new StringBuilder(), (acc, c) =>
{
if (c != ' ' || acc.Length == 0 || acc[acc.Length - 1] != ' ')
acc.Append(c);
return acc;
}).ToString();
}
public static void Main()
{
const string input = " (five leading spaces) (five internal spaces) (five trailing spaces) ";
Console.WriteLine(" Input: \"{0}\"", input);
Console.WriteLine("Output: \"{0}\"", StringExtension.CondenseSpaces(input));
}
}
Executing this program produces the following output:
Input: " (five leading spaces) (five internal spaces) (five trailing spaces) "
Output: " (five leading spaces) (five internal spaces) (five trailing spaces) "
Old skool:
string oldText = " 1 2 3 4 5 ";
string newText = oldText
.Replace(" ", " " + (char)22 )
.Replace( (char)22 + " ", "" )
.Replace( (char)22 + "", "" );
Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );
You can create a StringsExtensions file with a method like RemoveDoubleSpaces().
StringsExtensions.cs
public static string RemoveDoubleSpaces(this string value)
{
Regex regex = new Regex("[ ]{2,}", RegexOptions.None);
value = regex.Replace(value, " ");
// this removes space at the end of the value (like "demo ")
// and space at the start of the value (like " hi")
value = value.Trim(' ');
return value;
}
And then you can use it like this:
string stringInput =" hi here is a demo ";
string stringCleaned = stringInput.RemoveDoubleSpaces();
I looked over proposed solutions, could not find the one that would handle mix of white space characters acceptable for my case, for example:
Regex.Replace(input, #"\s+", " ") - it will eat your line breaks, if they are mixed with spaces, for example \n \n sequence will be replaced with
Regex.Replace(source, #"(\s)\s+", "$1") - it will depend on whitespace first character, meaning that it again might eat your line breaks
Regex.Replace(source, #"[ ]{2,}", " ") - it won't work correctly when there's mix of whitespace characters - for example "\t \t "
Probably not perfect, but quick solution for me was:
Regex.Replace(input, #"\s+",
(match) => match.Value.IndexOf('\n') > -1 ? "\n" : " ", RegexOptions.Multiline)
Idea is - line break wins over the spaces and tabs.
This won't handle windows line breaks correctly, but it would be easy to adjust to work with that too, don't know regex that well - may be it is possible to fit into single pattern.
The following code remove all the multiple spaces into a single space
public string RemoveMultipleSpacesToSingle(string str)
{
string text = str;
do
{
//text = text.Replace(" ", " ");
text = Regex.Replace(text, #"\s+", " ");
} while (text.Contains(" "));
return text;
}