180 first characters of a string ending with a word - c#

I need to shorten a string down..
Lets say we have a string with the length 500.
I only want the first part of it - max 180 characters, ending with the last word before reaching the 180. I don't want to cut the string short in the middle of a word.
How is this achived? it does not have to perform all that well.. it is something that happens a couple of times a day, not more.

A really easy way is by using this regex:
string trimmed = Regex.Match(input,#"^.{1,180}\b").Value;
The only problem with that one is that it could contain trailing whitespace. To fix that, we can add a little negative look-behind:
string trimmed = Regex.Match(input,#"^.{1,180}\b(?<!\s)").Value;
That should do the trick.

How about looking at char 180, and move backwards to find the first char in (lets say space, comma, exclamation etc) indicating the start of the previous word?

Conceptially
Check that the string is over 180 characters long.
Grab the first 180 characters as a substring.
Return what you need by using the "LastIndexOf" method to get the length of the string combined with a substring to return the appropriate string.
In Code:
string InString;
InString = "Your long string goes here";
if (InString.Length>180) //Check the string length
{
InString = InString.Substring(0, 180); //Get the first 180 chars
InString = InString.Substring(0,InString.LastIndexOf(" ")); //Stop at the last space
}
This should return the correct string; though LastIndexOfAny will allow you ta add other characters to your EOL list.

You just use the normal commands on string class:
string short = myStr.Substring(0, 180);
int end = short.LastIndexOfAny(new char[] {' ', '\t', '\n'}); //maybe more
return short.Substring(0, end);

Related

Moving the first char in a string to the send of the string using a method. C#

I know there are a lot of similar questions asked, and I've looked over those, but I still can't figure out my solution.
I'm trying to write a method that takes the first character of an inputted string and moves it to the back, then I can add additional characters if needed.
Basically if the input is Hello the output would be elloH + "whatever." I hope that makes sense.
As proof that I'm just not being lazy, here is the rest of the source code for the other parts of what I am working on. It all works, I just don't know where to begin with the last part.
Thanks for looking and thanks for the help!
private string CaseSwap(string str)//method for swaping cases
{
string result = ""; //create blank var
foreach (var c in str)
if (char.IsUpper(c)) //find uppers
result += char.ToLower(c); //change to lower
else
result += char.ToUpper(c); //all other lowers changed to upper
str = result; //assign var to str
return str; //return string to method
}
private string Reverse(string str)//method for reversing string
{
char[] revArray = str.ToCharArray(); //copy into an array
Array.Reverse(revArray); //reverse the array
return new string(revArray); //return the new string
}
private string Latin(string str)//method for latin
{
}
}
}
If you want to move first character to the end of string, then you can try below
public string MoveFirstCharToEnd(string str, string whateverStr="")
{
if(string.IsNullOrEmpty(str))
return str;
string result = str.Substring(1) + str[0] + whateverStr;
return result;
}
Note: I added whateverStr as an optional parameter, so that it can support only moving first character to the end and also it supports concatenating extra string to the result.
String.Substring(Int32):
Retrieves a substring from this instance. The substring starts at a
specified character position and continues to the end of the string.
Why not just take the 1st char and combine it with the rest of the string? E.g.
Hello
^^ ^
|| |
|Substring(1) - rest of the string (substring starting from 1)
|
value[0] - first character
Code:
public static string Rotate(string value) => string.IsNullOrEmpty(value)
? value
: $"{value.Substring(1)}{value[0]}";
Generalized implementation for arbitrary rotation (either positive or negative):
public static string Rotate(string value, int count = 1) {
if (string.IsNullOrWhiteSpace(value))
return value;
return string.Concat(Enumerable
.Range(0, value.Length)
.Select(i => value[(i + count % value.Length + value.Length) % value.Length]));
}
You can simplify your current implementation with a help of Linq
using System.Linq;
...
private static string CaseSwap(string value) =>
string.Concat(value.Select(c => char.IsUpper(c)
? char.ToLower(c)
: char.ToUpper(c)));
private static string Reverse(string value) =>
string.Concat(value.Reverse());
You can try to get the first character of a string with the String.Substring(int startPosition, int length) method . With this method you can also get the rest of your text starting from position 1 (skip the first character). When you have these 2 pieces, you can concat them.
Don't forget to check for empty strings, this can be done with the String.IsNullOrEmpty(string text) method.
public static string RemoveAndConcatFirstChar(string text){
if (string.IsNullOrEmpty(text)) return "";
return text.Substring(1) + text.Substring(0,1);
}
Appending multiple characters to a string is inefficient due to the number of string objects allocated, which is not just memory intensive it's also slow. There's a reason we have StringBuilder and other such options available to us, like working with char[]s.
Here's a fairly quick method that for rotating a string left one character (moving the first character to the end):
string RotateLeft(string source)
{
var chars = source.ToCharArray();
var initial = chars[0];
Array.Copy(chars, 1, chars, 0, chars.Length - 1);
chars[^1] = initial;
return new String(chars);
}
Sadly we can't do that in-place in the string itself since they're immutable, so there's no avoiding the temporary array and string construction at the end.
Based on the fact that you called the method Latin(...) and the bit of the question where you said: "Basically if the input is Hello the output would be elloH + "whatever."... I'm assuming that you're writing a Pig Latin translation. If that's the case, you're going to need a bit more.
Pig Latin is a slightly tricky problem because it's based on the sound of the word, not the letters. For example, onto becomes ontohay (or variants thereof) while one becomes unway because the word is pronounced the same as won (with a u to capture the vowel pronunciation correctly). Phonetic operations on English is quite annoying because of all the variations with silent and implied initial letters. And don't even get me started on pseudo-vowels like y.
Special cases aside, the most common rules of Pig Latin translation code appear to be as follows:
Words starting with a single consonant followed by a vowel: move the consonant to the end and append ay.
Words starting with a pair of consonants followed by a vowel: move the consonant pair to the end and append ay.
Words that start with a vowel: append hay, yay, tay, etc.
That third one is a bit difficult since choosing the right suffix is a matter of what makes the result easiest to say... which code can't really decide all that easily. Just pick one and go with that.
Of course there are plenty of words that don't fit those rules. Anything starting with a consonant triplet for example (Christmas being the first that came to mind, followed shortly by strip... and others). Pseudo-vowels like y mess things up (cry for instance). And of course the ever-present problem of correctly representing the initial vowel sounds when you've stripped context: won is converted to un-way vocally, so rendering it as on-way in text is a little bit wrong. Same with word, whose Pig Latin version is pronounced erd-way.
For a simple first pass though... just follow the rules, treating y as a consonant if it's the first letter and as a vowel in the second or third spots.
And since this is so often a homework problem, I'm going to stop here and let you play with it for a bit. Just in case :P
(Oh, and don't forget to preserve the case of your first character just in case you're working on a capitalized word. Latin should become Atinlay, not atinLay. Just saying.)

Adding whitespaces to a string in C#

I'm getting a string as a parameter.
Every string should take 30 characters and after I check its length I want to add whitespaces to the end of the string.
E.g. if the passed string is 25 characters long, I want to add 5 more whitespaces.
The question is, how do I add whitespaces to a string?
You can use String.PadRight for this.
Returns a new string that left-aligns the characters in this string by padding them with spaces on the right, for a specified total length.
For example:
string paddedParam = param.PadRight(30);
You can use String.PadRight method for this;
Returns a new string of a specified length in which the end of the
current string is padded with spaces or with a specified Unicode
character.
string s = "cat".PadRight(10);
string s2 = "poodle".PadRight(10);
Console.Write(s);
Console.WriteLine("feline");
Console.Write(s2);
Console.WriteLine("canine");
Output will be;
cat feline
poodle canine
Here is a DEMO.
PadRight adds spaces to the right of strings. It makes text easier to
read or store in databases. Padding a string adds whitespace or other
characters to the beginning or end. PadRight supports any character
for padding, not just a space.
Use String.PadRight which will space out a string so it is as long as the int provided.
var str = "hello world";
var padded = str.PadRight(30);
// padded = "hello world "
you can use Padding in C#
eg
string s = "Example";
s=s.PadRight(30);
I hope It will resolve your problem.

Remove the last three characters from a string

I want to remove last three characters from a string:
string myString = "abcdxxx";
Note that the string is dynamic data.
read last 3 characters from string [Initially asked question]
You can use string.Substring and give it the starting index and it will get the substring starting from given index till end.
myString.Substring(myString.Length-3)
Retrieves a substring from this instance. The substring starts at a
specified character position. MSDN
Edit, for updated post
Remove last 3 characters from string [Updated question]
To remove the last three characters from the string you can use string.Substring(Int32, Int32) and give it the starting index 0 and end index three less than the string length. It will get the substring before last three characters.
myString = myString.Substring(0, myString.Length-3);
String.Substring Method (Int32, Int32)
Retrieves a substring from this instance. The substring starts at a
specified character position and has a specified length.
You can also using String.Remove(Int32) method to remove the last three characters by passing start index as length - 3, it will remove from this point to end of string.
myString = myString.Remove(myString.Length-3)
String.Remove Method (Int32)
Returns a new string in which all the characters in the current
instance, beginning at a specified position and continuing through the
last position, have been deleted
myString = myString.Remove(myString.Length - 3, 3);
I read through all these, but wanted something a bit more elegant. Just to remove a certain number of characters from the end of a string:
string.Concat("hello".Reverse().Skip(3).Reverse());
output:
"he"
The new C# 8.0 range operator can be a great shortcut to achieve this.
Example #1 (to answer the question):
string myString = "abcdxxx";
var shortenedString = myString[0..^3]
System.Console.WriteLine(shortenedString);
// Results: abcd
Example #2 (to show you how awesome range operators are):
string s = "FooBar99";
// If the last 2 characters of the string are 99 then change to 98
s = s[^2..] == "99" ? s[0..^2] + "98" : s;
System.Console.WriteLine(s);
// Results: FooBar98
myString.Remove(myString.Length-3);
string test = "abcdxxx";
test = test.Remove(test.Length - 3);
//output : abcd
You can use String.Remove to delete from a specified position to the end of the string.
myString = myString.Remove(myString.Length - 3);
Probably not exactly what you're looking for since you say it's "dynamic data" but given your example string, this also works:
? "abcdxxx".TrimEnd('x');
"abc"
If you're working in C# 8 or later, you can use "ranges":
string myString = "abcdxxx";
string trimmed = myString[..^3]; // "abcd"
More examples:
string test = "0123456789", s;
char c;
c = test[^3]; // '7'
s = test[0..^3]; // "0123456"
s = test[..^3]; // "0123456"
s = test[2..^3]; // "23456"
s = test[2..7]; // "23456"
//c = test[^12]; // IndexOutOfRangeException
//s = test[8..^3]; // ArgumentOutOfRangeException
s = test[7..^3]; // string.Empty
str= str.Remove(str.Length - 3);
myString.Substring(myString.Length - 3, 3)
Here are examples on substring.>>
http://www.dotnetperls.com/substring
Refer those.
string myString = "abcdxxx";
if (myString.Length<3)
return;
string newString=myString.Remove(myString.Length - 3, 3);
Easy. text = text.remove(text.length - 3). I subtracted 3 because the Remove function removes all items from that index to the end of the string which is text.length. So if I subtract 3 then I get the string with 3 characters removed from it.
You can generalize this to removing a characters from the end of the string, like this:
text = text.remove(text.length - a)
So what I did was the same logic. The remove function removes all items from its inside to the end of the string which is the length of the text. So if I subtract a from the length of the string that will give me the string with a characters removed.
So it doesn't just work for 3, it works for all positive integers, except if the length of the string is less than or equal to a, in that case it will return a negative number or 0.
Remove the last characters from a string
TXTB_DateofReiumbursement.Text = (gvFinance.SelectedRow.FindControl("lblDate_of_Reimbursement") as Label).Text.Remove(10)
.Text.Remove(10)// used to remove text starting from index 10 to end
items.Remove(items.Length - 3)
string.Remove() removes all items from that index to the end. items.length - 3 gets the index 3 chars from the end
You can call the Remove method and pass the last 3 characters
str.Substring(str.Length-3)
Complete code can be
str.Remove(str.Substring(str.Length-3));

Regular expression to split long strings in several lines

I'm not an expert in regular expressions and today in my project I face the need to split long string in several lines in order to check if the string text fits the page height.
I need a C# regular expression to split long strings in several lines by "\n", "\r\n" and keeping 150 characters by line maximum. If the character 150 is in the middle of an word, the entire word should be move to the next line.
Can any one help me?
It's actually a quite simple problem. Look for any characters up to 150, followed by a space. Since Regex is greedy by nature it will do exactly what you want it to. Replace it by the Match plus a newline:
.{0,150}(\s+|$)
Replace with
$0\r\n
See also: http://regexhero.net/tester/?id=75645133-1de2-4d8d-a29d-90fff8b2bab5
var regex = new Regex(#".{0,150}", RegexOptions.Multiline);
var strings = regex.Replace(sourceString, "$0\r\n");
Here you go:
^.{1,150}\n
This will match the longest initial string like this.
if you just want to split a long string into lines of 150 chars then I'm not sure why you'd need a regular expression:
private string stringSplitter(string inString)
{
int lineLength = 150;
StringBuilder sb = new StringBuilder();
while (inString.Length > 0)
{
var curLength = inString.Length >= lineLength ? lineLength : inString.Length;
var lastGap = inString.Substring(0, curLength).LastIndexOfAny(new char[] {' ', '\n'});
if (lastGap == -1)
{
sb.AppendLine(inString.Substring(0, curLength));
inString = inString.Substring(curLength);
}
else
{
sb.AppendLine(inString.Substring(0, lastGap));
inString = inString.Substring(lastGap + 1);
}
}
return sb.ToString();
}
edited to account for word breaks
This code should help you. It will check the length of the current string. If it is greater than your maxLength (150) in this case, it will start at the 150th character and (going backwards) find the first non-word character (as described by the OP, this is a sequence of non-space characters). It will then store the string up to that character and start over again with the remaining string, repeating until we end up with a substring that is less than maxLength characters. Finally, join them all back together again in a final string.
string line = "This is a really long run-on sentence that should go for longer than 150 characters and will need to be split into two lines, but only at a word boundary.";
int maxLength = 150;
string delimiter = "\r\n";
List<string> lines = new List<string>();
// As long as we still have more than 'maxLength' characters, keep splitting
while (line.Length > maxLength)
{
// Starting at this character and going backwards, if the character
// is not part of a word or number, insert a newline here.
for (int charIndex = (maxLength); charIndex > 0; charIndex--)
{
if (char.IsWhiteSpace(line[charIndex]))
{
// Split the line after this character
// and continue on with the remainder
lines.Add(line.Substring(0, charIndex+1));
line = line.Substring(charIndex+1);
break;
}
}
}
lines.Add(line);
// Join the list back together with delimiter ("\r\n") between each line
string final = string.Join(delimiter , lines);
// Check the results
Console.WriteLine(final);
Note: If you run this code in a console application, you may want to change "maxLength" to a smaller number so that the console doesn't wrap on you.
Note: This code does not take into effect any tab characters. If tabs are also included, your situation gets a bit more complicated.
Update: I fixed a bug where new lines were starting with a space.

c# Best way to break up a long string

This question is not related to:
Best way to break long strings in C# source code
Which is about source, this is about processing long outputs. If someone enters:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
As a comment, it breaks the container and makes the entire page really wide. Is there any clever regexp that can say, define a maximum word length of 20 chars and then force a whitespace character?
Thanks for any help!
There's probably no need to involve regexes in something this simple. Take this extension method:
public static string Abbreviate(this string text, int length) {
if (text.Length <= length) {
return text;
}
char[] delimiters = new char[] { ' ', '.', ',', ':', ';' };
int index = text.LastIndexOfAny(delimiters, length - 3);
if (index > (length / 2)) {
return text.Substring(0, index) + "...";
}
else {
return text.Substring(0, length - 3) + "...";
}
}
If the string is short enough, it's returned as-is. Otherwise, if a "word boundary" is found in the second half of the string, it's "gracefully" cut off at that point. If not, it's cut off the hard way at just under the desired length.
If the string is cut off at all, an ellipsis ("...") is appended to it.
If you expect the string to contain non-natural-language constructs (such as URLs) you 'd need to tweak this to ensure nice behavior in all circumstances. In that case working with a regex might be better.
You could try using a regular expression that uses a positive look-ahead like this:
string outputStr = Regex.Replace(inputStr, #"([\S]{20}(?=\S+))", "$1\n");
This should "insert" a line break into all words that are longer than 20 characters.
Yes you can use this one regex
string pattern = #"^([\w]{1,20})$";
this regex allow to enter not more than 20 characters
string strRegex = #"^([\w]{1,20})$";
string strTargetString = #"asdfasfasfasdffffff";
if(Regex.IsMatch(strTargetString, strRegex))
{
//do something
}
If you need only lenght constraint you should use this regex
^(.{1,20})$
because the \w is match only
alphanumeric and underscore symbol

Categories

Resources