I am writing a program to check if a word is palindrome. The program itself works
but when I enter this specific line of text "too bad - i hid a boot" it will not pick it up
and ignore the white space and hyphen.
I looked at previous questions but I cant find a answer.
Is my Regex.Replace incorrect?
string s, revs = "";
Console.WriteLine("Please Enter Word");
s = Console.ReadLine();
string r = Regex.Replace(s , #"[^-\s]", "");
for (int i = s.Length-1; i >= 0; i--)
{
revs += s[i].ToString();
}
if (revs == s)
{
Console.WriteLine("Entered string is palindrome \n String was {0} and reverse string was {1}", s, revs);
}
else
{
Console.WriteLine("String entered was not palindrome.");
}
Console.ReadKey();
Your code contains two errors:
This is the correct Regex condition #"(\s|-)" yours replaces everything but the characters you want to remove
As jeffdot pointed out, you're replacing (incorrectly) but then testing against the original string
This considered, the correct code should be:
string s, revs = "";
Console.WriteLine("Please Enter Word");
s = Console.ReadLine();
string r = Regex.Replace(s , #"(\s|-)", "");
for (int i = r.Length-1; i >= 0; i--)
{
revs += r[i].ToString();
}
if (revs == r)
{
Console.WriteLine("Entered string is palindrome \n String was {0} and reverse string was {1}", s, revs);
}
else
{
Console.WriteLine("String entered was not palindrome.");
}
Console.ReadKey();
Except for the first WriteLine in which you should decide what to print (since revs doesn't contain spaces and the hyphen anymore).
Or if you want to just use String.Replace, you can use it twice with:
s=s.Replace(' ','');
s=s.Replace('-','');
You are assigning the result of that Regex.Replace call to string r and you are never referencing it. This is why your comparison is failing.
To make that more clear: you are removing whitespace and referencing that product as string r but you are reversing and testing against string s only.
Saverio also points out that your regex isn't going to work (I didn't test that myself).
You have:
string r = Regex.Replace(s , #"[^-\s]", "");
for (int i = s.Length-1; i >= 0; i--)
{
revs += s[i].ToString();
}
Right there you should be iterating and reversing r instead of s --because s still has all its whitespace.
Further, as Saverio has said, why not just replace?
string r = s.Replace(" ", string.Empty).Reverse();
I haven't tried to compile that but as long as you are not using a very old version of the .NET framework that should work. It may require that you are using System.Linq to use the Reverse() extension.
Related
For instance, I have a string and I only want the character '<' to appear 10 times in the string, and create a substring where the cutoff point is the 10th appearance of that character. Is this possible?
A manual solution could be like the following:
class Program
{
static void Main(string[] args)
{
int maxNum = 10;
string initialString = "a<b<c<d<e<f<g<h<i<j<k<l<m<n<o<p<q<r<s<t<u<v<w<x<y<z";
string[] splitString = initialString.Split('<');
string result = "";
Console.WriteLine(splitString.Length);
if (splitString.Length > maxNum)
{
for (int i = 0; i < maxNum; i++) {
result += splitString[i];
result += "<";
}
}
else
{
result = initialString;
}
Console.WriteLine(result);
Console.ReadKey();
}
}
By the way, it may be better to try to do it using Regex (in case you may have other replacement rules in the future, or need to make changes, etc). However, given your problem, something like that will work, too.
You can utilize TakeWhile for your purpose, given the string s, your character < as c and your count 10 as count, following function would solve your problem:
public static string foo(string s, char c, int count)
{
var i = 0;
return string.Concat(s.TakeWhile(x => (x == c ? i++ : i) < count));
}
Regex.Matches can be used to count the number of occurrences of a patter in a string.
It also reference the position of each occurrence, the Capture.Index property.
You can read the Index of the Nth occurrence and cut your string there:
(The RegexOptions are there just in case the pattern is something different. Modify as required.)
int cutAtOccurrence = 10;
string input = "one<two<three<four<five<six<seven<eight<nine<ten<eleven<twelve<thirteen<fourteen<fifteen";
var regx = Regex.Matches(input, "<", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
if (regx.Count >= cutAtOccurrence) {
input = input.Substring(0, regx[cutAtOccurrence - 1].Index);
}
input is now:
one<two<three<four<five<six<seven<eight<nine<ten
If you need to use this procedure many times, it's bettern to build a method that returns a StringBuilder instead.
I have a string that contains several instances of a substring, as well as other text. The substring is specified by beginning with a given sequence of letters (e.g. CNTY) and ending with a double slash (//). How could I efficiently remove all text that does not fall inside the specified substring? Thanks for the help. I found that this Regex will return the result needed:
string result = Regex.Matches(text, "CNTY(.*)//").Cast<Match>().Aggregate("", (s, t) => s + t.Value, s => s);
But, I have another more complicated substring, which begins with WEATHLOC, then contains wildcard text across several lines, and ends with a line beginning RMKS, more wildcard text, and then //. Here is an example:
WEATHLOC/ICAO:KCOS//
OBSTIME/052005Z//
WIND/360/10//
VSBY/10/SM//
CLDLYR/-/LYR:BKN//
TEMP/MAXTEMP:15/MINTEMP:18//
ALTSTG/HG:29.92//
RMKS/SAMPLE//
Everything from WEATHLOC to the final // needs to be captured, and I can only rely on its beginning with WEATHLOC and ending with RMKS*//. Is there a way to express that in a Regex match?
This should work:
string text = "hiCNTYhello//content What /-CNTYworld//12texCNTY!//That's it";
string search = "CNTY(.*?)//";
MatchCollection matches = Regex.Matches(text, search);
Will match "hello", "world" and "!"
This little code segment works. The RegEx method was too difficult for me, but this does work. We are trying to check if we are in bounds of CNTY // and to output that text to the StringBuilder.
static void Main(string[] args)
{
var input = #"CNTYTestingTesting//This is some more test CNTY1234//And some moreCNTYWhat is this?//";
var sb = new StringBuilder();
int inCnty = -1;
for (int i = 0; i < input.Length; i ++)
{
// Test for start
if (i < input.Length - 4)
{
if (input.Substring(i, 4) == "CNTY")
{
inCnty = i + 4; // Index of first CNTY
}
}
// Test for end
if (i < input.Length - 1)
{
if (input.Substring(i, 2) == #"//")
{
inCnty = -1; // Reset
}
}
// Test if we are in the segment
if (i >= inCnty && inCnty > 0)
{
// Outside string
sb.Append(input[i]);
}
}
var output = sb.ToString();
Console.WriteLine(output);
Console.Read();
}
How can I search for a word within a string ?
I have one text box which the user insert a string and another on with with text just some random text.
Are there any alterative ways of doing this besides using regex and IndexOf? Like using a for loop and checking the length and character in the word.
This is what I tried so far
int i = 0;
int count = 0;
input2.Trim();
while ((i = input2.IndexOf(input1, i)) != -1)
{
i = i + input1.Length;
count++;
}
MessageBox.Show(count.ToString() + " Matches Found");
Looks like you want to get the Count of search string in the text. You can try the following.
string searchString = "TEST";
string completeText = "Some sentence TEST with other words incluing TEST";
int count = completeText.Split(new string[]{"TEST"},StringSplitOptions.None)
.Count() - 1;
MessageBox.Show(count.ToString() + " Matches Found");
Use a regex to match the number of occurances,
string test = "THE DOG WENT TO TOWN DOG";
int j = Regex.Matches(test, "DOG").Cast<Match>().Count();
I have a code in C# and have to print a label with the name of the seller, but i have a problem.
Every line in the label comport 20 letters and i have 2 lines to put this name.
I need to arrange the name of the seller in the 2 lines, without cut words.
For example - Name: JOSE MAURICIO BERTOLOTO MENDES
Line1: JOSE MAURICIO
Line2: BERTOLOTO MENDES
someone know how i do this?
Thanks
EDIT: Based in the answers, i implemente this code:
string[] SellerPrint = Seller.Split(' ');
Line1 = "";
Line2 = "";
foreach (string name in SellerPrint )
{
if (Line1.Length <= 20)
{
if ((Line1 + name).Length <= 20)
Line1 += (Line1.Length == 0) ? name : " " + name;
else
break;
}
}
Line2 = (Seller.Replace(Line1, "").Length <= 20) ? Seller.Replace(Line1+ " ", "") : Seller.Replace(Line1+ " ", "").Remove(20);
Thanks for the help!
You could simply split the string into words using string.Split() and then add to each as long it small enough to add to the line.
I also wouldn't use the character count but use Graphics.MeasureString() instead.
You can split the full name in to it's individual parts.
var names = fullname.Split(' ');
Which will give you a string[]. From there you can do the math by looking at length of each string.
The idea is that you want to append all parts of the name until you will reach or exceed your 20 character limit on the next token. When that happens, append a new line with that token and continue appending until you hit the character limit once again.
Here is a quick example:
public static string FormatName(string name)
{
const int MaxLength = 20;
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
if (name.Length <= MaxLength)
return name;
string[] tokens = name.Split(' ');
if (tokens.Length == 0)
return name; //hyphen the name?
StringBuilder sb = new StringBuilder(name.Length);
int len = 0;
foreach (string token in tokens)
{
if (token.Length + len < MaxLength)
{
sb.Append(token + " ");
len += token.Length;
}
else
{
sb.Append(Environment.NewLine + token + " ");
len = 0;
}
}
return sb.ToString();
}
Note: I left the case open for when a section of the name, without spaces, is longer than 20 characters. Also, this example will continue on to the Nth line, if the name won't fit onto two lines.
Here is the logic.
Use String.split to split the name into an array. Iterate over the strings in the array, concat them into a line, while the line is less than 20 characters. A recursive function would be a good idea! When you are greater than two lines, drop the rest of the names that put it over.
I'm not sure but I think you can use a special character: '\n' (without the quotes)
Its basiclly stands for new line. So for example : JOSE MAURICIO BERTOLOTO MENDES will become JOSE MAURICIO \n BERTOLOTO MENDES.
i wrote a code for replacing lowercase characters to *.
but it does not work.
where is the problem?
private void CharacterReplacement()
{
Console.WriteLine("Enter a string to replacement : ");
string TargetString = Console.ReadLine();
string MainString = TargetString;
for (int i = 0; i < TargetString.Length; i++)
{
if (char.IsLower(TargetString[i]))
{
TargetString.Replace(TargetString[i], '*');
}
}
Console.WriteLine("The string {0} has converted to {1}", MainString, TargetString);
}
Replace() returns a new string, so you need to re-assign it to TargetString:
TargetString = TargetString.Replace(TargetString[i], '*');
Another way to express your intend would be with Linq - not sure which I like better, this avoids all the temporary strings but has other overhead:
TargetString = new string(TargetString.Select(c => char.IsLower(c) ? '*' : c)
.ToArray());
You can of course write this in one short line by using a regular expression:
string output = Regex.Replace("ABCdef123", "[a-z]", "*"); // output = "ABC***123"
Improved version based on Arto's comment, that handles all lowercase unicode characters:
string output = Regex.Replace("ABCdefëï123", "\p{Ll}", "*"); // output = "ABC*****123"