I have the following code for converting a string containing alphanumeric characters to a string of numbers that can be entered into a phone using the phone's keypad:
string text = "sometext containing spaces and numbers 12345";
Dictionary<char, char> alphabetMapping = new Dictionary<char, char>();
alphabetMapping['a'] = '2';
alphabetMapping['b'] = '2';
alphabetMapping['c'] = '2';
alphabetMapping['d'] = '3';
alphabetMapping['e'] = '3';
alphabetMapping['f'] = '3';
alphabetMapping['g'] = '4';
alphabetMapping['h'] = '4';
alphabetMapping['i'] = '4';
alphabetMapping['j'] = '5';
alphabetMapping['k'] = '5';
alphabetMapping['l'] = '5';
alphabetMapping['m'] = '6';
alphabetMapping['n'] = '6';
alphabetMapping['o'] = '6';
alphabetMapping['p'] = '7';
alphabetMapping['q'] = '7';
alphabetMapping['r'] = '7';
alphabetMapping['s'] = '7';
alphabetMapping['t'] = '8';
alphabetMapping['u'] = '8';
alphabetMapping['v'] = '8';
alphabetMapping['w'] = '9';
alphabetMapping['x'] = '9';
alphabetMapping['y'] = '9';
alphabetMapping['z'] = '9';
alphabetMapping['1'] = '1';
alphabetMapping['2'] = '2';
alphabetMapping['3'] = '3';
alphabetMapping['4'] = '4';
alphabetMapping['5'] = '5';
alphabetMapping['6'] = '6';
alphabetMapping['7'] = '7';
alphabetMapping['8'] = '8';
alphabetMapping['9'] = '9';
alphabetMapping['0'] = '0';
alphabetMapping['.'] = '0';
alphabetMapping[','] = '0';
alphabetMapping['#'] = '0';
alphabetMapping['*'] = '*';
alphabetMapping['#'] = '#';
alphabetMapping[' '] = '0'; // not sure if this underscore or space
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
sb.Append(alphabetMapping[c]);
}
Console.WriteLine(sb.ToString());
The output:
76638398026682464640772237026306862377012345
Not that this has much practical use, but some automated phone systems ask for passwords that may contain letters so I wrote this code for helping with that.
Is there a more efficient method for this or am I on the right track?
An elegant way to convert phone letters to their respective numbers is to use Regular Expressions. Here is the function that I use. It may need to be tweaked to fit your scenario.
internal static string ConvertPhoneTexttoNumber(string PhoneNumber)
{
PhoneNumber = Regex.Replace(PhoneNumber, #"[abcABC]", "2");
PhoneNumber = Regex.Replace(PhoneNumber, #"[defDEF]", "3");
PhoneNumber = Regex.Replace(PhoneNumber, #"[ghiGHI]", "4");
PhoneNumber = Regex.Replace(PhoneNumber, #"[jklJKL]", "5");
PhoneNumber = Regex.Replace(PhoneNumber, #"[mnoMNO]", "6");
PhoneNumber = Regex.Replace(PhoneNumber, #"[pgrsPGRS]", "7");
PhoneNumber = Regex.Replace(PhoneNumber, #"[tuvTUV]", "8");
PhoneNumber = Regex.Replace(PhoneNumber, #"[wxyzWXYZ]", "9");
//remove all non alphanumeric characters
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
return PhoneNumber;
}
This solution will work for any number of characters in a string. If you want to keep the parentheses and dashes remove this line:
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
Note: If you don't know how to use Regular Expressions, here is a great tutorial:
https://regexone.com/lesson/introduction_abcs
You could use fewer lines of code if you grouped all of your items together.
var allValues = new List<KeyValuePair<string,char>>()
allValues.Add(new KeyValuePair("abc2","2"));
allValues.Add(new KeyValuePair("def3","3"));
etc, etc
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
var matched = allValues.FirstOrDefault(kvp=> kvp.Key.Contains(c));
if(matched != null)
{
sb.Append(matched.Value);
}
else
{
sb.Append(" ");
}
}
Console.WriteLine(sb.ToString());
It's probably not computationally more efficient, but it's less for a human to read.
Considering the size of the dataset (alphanumeric characters and letters) and the intended application, this seems like the most logical and seemingly optimal way to do it. If you wanted to improve the performance you could use a HashSet, but I'm not sure you would see any measurable gain from that with this dataset.
Related
I need convert a phrase words in uppercase and lowercase continuous (alternating).
Example.
Input:
the girl is pretty.
Output:
tHe GiRl Is PrEtTy
I have tried the code below but it only convert the first letter:
char[] array = texto.ToCharArray();
if (array.Length >= 1)
{
if (char.IsLower(array[0]))
{
array[0] = char.ToUpper(array[0]);
}
}
for (int i = 1; i < array.Length; i++)
{
if (array[i - 1] == ' ')
{
if (char.IsLower(array[i]))
{
array[i] = char.ToUpper(array[i]);
}
}
}
return new string(array);
Thanks
Fancy solution using LINQ:
string someString = "the girl is pretty";
string newString = string.Concat(
someString.ToLower().AsEnumerable().Select((c, i) => i % 2 == 0 ? c : char.ToUpper(c)));
This basically does the following:
Convert the string to lowercase.
Iterate over each character.
Convert every second character to upper case.
Join the characters into a single string.
A more “classical” solution could look like this:
string someString = "the girl is pretty";
StringBuilder sb = new StringBuilder();
bool uppercase = false;
foreach (char c in someString)
{
if (uppercase)
sb.Append(char.ToUpper(c));
else
sb.Append(char.ToLower(c));
uppercase = !uppercase;
}
string newString = sb.ToString();
Answer by poke was right, however it includes the spaces on alternating the case. I do some tweak to the previous answer, it ignores the spaces of the string.
string someString = "the girl is pretty";
string space = " ";
char[] str = someString.ToCharArray();
char[] str2 = space.ToCharArray();
bool uppercase = false;
StringBuilder sb = new StringBuilder();
foreach (char c in str)
{
if (c != str2[0])
{
if (uppercase)
sb.Append(char.ToUpper(c));
else
{
sb.Append(char.ToLower(c));
}
uppercase = !uppercase;
}
else
{
sb.Append(c);
}
}
string newString = sb.ToString();
I have one resume , i want to find user's contact number(Mobile no or Phone no)
from the resume, Need any idea or solution or any assistance for achieving the goal .
What i Have tried so far....
var numString = "";
string strData = ",38,,,,,,,,,,,,,,,,,,,,,,,,,,,,382350,,,,,0,,,,8141884584,,,,,,,,";
char[] separator = new char[] { ',' };
string[] strSplitArr = strData.Split(separator);
for (int q = 0; q < strSplitArr.Length; q++)
{
if (strSplitArr[q] != "")
{
int no = 0;
no = strSplitArr[q].Length;
if (no >= 10 && no <= 12)
{
numString += strSplitArr[q].ToString() + ", ";
}
}
}
I would suggest that you use Regular Expression
Here is a sample code to find US Phone numbers:
string text = MyInputMethod();
const string MatchPhonePattern =
#"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}";
Regex rx = new Regex(MatchPhonePattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
// Find matches.
MatchCollection matches = rx.Matches(text);
// Report the number of matches found.
int noOfMatches = matches.Count;
//Do something with the matches
foreach (Match match in matches)
{
//Do something with the matches
string tempPhoneNumber= match.Value.ToString(); ;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to make a random "password" generator that generates a length of different letters. You input the length and it make length random characters. I also want some random letters to be capitalized. I have a variable rndCap which to 1 or 2. The if will turn it into a capital letter if rndCap == 2, if not, it does nothing. The answer is all of the characters combined. When I execute, the numbers are all lowercase. Everything works except for it randomly capitalizing a character.
Random rnd = new Random();
string[] alphabet = new string[27];
alphabet[1] = "a";
alphabet[2] = "b";
alphabet[3] = "c";
alphabet[4] = "d";
alphabet[5] = "e";
alphabet[6] = "f";
alphabet[7] = "g";
alphabet[8] = "h";
alphabet[9] = "i";
alphabet[10] = "j";
alphabet[11] = "k";
alphabet[12] = "l";
alphabet[13] = "m";
alphabet[14] = "n";
alphabet[15] = "o";
alphabet[16] = "p";
alphabet[17] = "q";
alphabet[18] = "r";
alphabet[19] = "s";
alphabet[20] = "t";
alphabet[21] = "u";
alphabet[22] = "v";
alphabet[23] = "w";
alphabet[24] = "x";
alphabet[25] = "y";
alphabet[26] = "z";
string answer = "";
int length = Convert.ToInt32(lengthTextBox.Text);
int rndCap;
int rndLetter;
for (int i = 1; i <= length; i++)
{
rndCap = rnd.Next(1, 3);
rndLetter = rnd.Next(1, 27);
string tempMem = alphabet[rndLetter];
if (rndCap == 2)
{
tempMem.ToUpper();
}
answer = answer + tempMem;
}
passwordTextBox.Text = answer;
I'm pretty sure the IF is working :)
String.ToUpper() however doesn't change the string at hand to uppercase, but returns it as the result. You have to assign the value. What you wanted is probably this:
tempMem = tempMem.ToUpper();
Also, a rule to follow: Always bear in mind, that the
encoding, the culture and the locale can be different than that of your current one.
Even though in this case, we are only using "harmless-looking" ASCII characters, but to translate this into practice with uppercasing strings:
use the ToUpper(CultureInfo) to specify a culture
use the ToUpperInvariant() to use the "invariant culture" instead of the default one
As Jeppe noted: in the Turkish locale, i is uppercased to a character different from I - introducing unwanted consequences.
string is immutable so you need to assign it again
tempMem = tempMem.ToUpper();
You call ToUpper, but don't assign the value:
tempMem = tempMem.ToUpper()
Maybe this code is in general more elegant:
static void Main(string[] args)
{
Random cRandom = new Random(DateTime.Now.Millisecond);
string answer = "";
int length = Convert.ToInt32(6);
int rndCap;
int rndLetter;
for (int i = 1; i <= length; i++)
{
rndCap = cRandom.Next(1, 3);
rndLetter = cRandom.Next(0, 26);
char tempMem = (char)('a' + rndLetter);
string c2 = tempMem.ToString();
if (rndCap == 2)
{
c2 = tempMem.ToString().ToUpper();
}
answer = answer + c2;
}
Console.WriteLine(answer);
Console.ReadLine();
}
use this:
tempMem = tempMem.ToUpper();
as ToUpper() doesn't make uppercasing to string it is invoked on, it returns copy of this string with all letters uppercased.
ToUpper() is a method that returns an uppercase string, so you need to assign the value of tempMem to that value:
tempMem = tempMem.ToUpper();
All string manipulations returns the new string and not modifying the original since string is imutable.
Modify it like that: tempMem = tempMem.ToUpper();
I think there are simpler ways to perform what you want to achieve. Have a look at this code;
var lowerchar = "abcdefghijklmnopqrstuvwxyz";
var upperchar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(lowerchar, 3)
.Select(s => s[random.Next(s.Length)])
.ToArray());
result += new string(
Enumerable.Repeat(upperchar, 3)
.Select(s => s[random.Next(s.Length)])
.ToArray());
result += new string(
Enumerable.Repeat(numbers, 2)
.Select(s => s[random.Next(s.Length)])
.ToArray());
random = new Random();
string password = new string(result.ToCharArray().OrderBy(s => random.Next().ToArray());
I have a file which contains lots of numbers which I want to reduce to construct a new file. First, I extract all the text using File.ReadAllText, then I split and extract numbers from each line that contains a number which are separated by commas or spaces. After scan, I replace all occurrences of each found number with the new reduced number but the problem is that this method is error prone since some numbers get replaced more than once
Here's the code I'm using:
List<float> oPaths = new List<float>();
List<float> nPaths = new List<float>();
var far = File.ReadAllText("paths.js");
foreach(var s in far.Split('\n'))
{
//if it starts with this that means there are some numbers
if (s.StartsWith("\t\tpath:"))
{
var paths = s.Substring(10).Split(new[]{',', ' '});
foreach(var n in paths)
{
float di;
if(float.TryParse(n, out di))
{
if(oPaths.Contains(di)) break;
oPaths.Add(di);
nPaths.Add(di * 3/4);
}
}
}
}
//second iteration to replace old numbers with new ones
var ns = far;
for (int i = 0; i < oPaths.Count; i++)
{
var od = oPaths[i].ToString();
var nd = nPaths[i].ToString();
ns = ns.Replace(od, nd);
}
File.WriteAllText("npaths.js", ns);
As you can see, the above method is redundant as it does not replace the strings on real time. Maybe my head is full, but I'm just lost on how to go about this. Any ideas?
Thanks.
I think a regex can help here
string text = File.ReadAllText(file);
string newtext = Regex.Replace(text, #"\b(([0-9]+)?\.)?[0-9]+\b", m =>
{
float f;
if (float.TryParse(m.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out f)) f *= 3.0f / 4;
return f.ToString();
});
File.WriteAllText(file, newtext);
Just after typing the question I realized the answer was to iterate character by character and replace accordingly. Here's the code I used to get this to work:
string nfar = "";
var far = File.ReadAllText("paths.js");
bool neg = false;
string ccc = "";
for(int i = 0; i < far.Length; i++)
{
char c = far[i];
if (Char.IsDigit(c) || c == '.')
{
ccc += c;
if (far[i + 1] == ' ' || far[i + 1] == ',')
{
ccc = neg ? "-" + ccc : ccc;
float di;
if (float.TryParse(ccc, out di))
{
nfar += (di*0.75f).ToString();
ccc = "";
neg = false;
}
}
}
else if (c == '-')
{
neg = true;
}
else
{
nfar += c;
}
}
File.WriteAllText("nfile.js", nfar);
Comments and/or optimization suggestions are welcome.
I'm using asp.net 4 and c#.
I have a string that can contains:
Special Characters, like: !"£$%&/()/#
Accented letters, like: àòèù
Empty spaces, like: " "(1 consecutive or more),
Example string:
#Hi this is rèally/ special strìng!!!
I would like to:
a) Remove all Special Characters, like:
Hi this is rèally special strìng
b) Convert all Accented letters to NON Accented letters, like:
Hi this is really special string
c) Remove all Empty spaces and replace theme with a dash (-), like:
Hi-this-is-really-special-string
My aim is to creating a string suitable for URL path for better SEO.
Any idea how to do it with Regular Expression or another techniques?
Thanks for your help on this!
Similar to mathieu's answer, but more custom made for you requirements. This solution first strips special characters and diacritics from the input string, and then replaces whitespace with dashes:
string s = "#Hi this is rèally/ special strìng!!!";
string normalized = s.Normalize(NormalizationForm.FormD);
StringBuilder resultBuilder = new StringBuilder();
foreach (var character in normalized)
{
UnicodeCategory category = CharUnicodeInfo.GetUnicodeCategory(character);
if (category == UnicodeCategory.LowercaseLetter
|| category == UnicodeCategory.UppercaseLetter
|| category == UnicodeCategory.SpaceSeparator)
resultBuilder.Append(character);
}
string result = Regex.Replace(resultBuilder.ToString(), #"\s+", "-");
See it in action at ideone.com.
You should have a look a this answer : Ignoring accented letters in string comparison
Code here :
static string RemoveDiacritics(string sIn)
{
string sFormD = sIn.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
foreach (char ch in sFormD)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
if (uc != UnicodeCategory.NonSpacingMark)
{
sb.Append(ch);
}
}
return (sb.ToString().Normalize(NormalizationForm.FormC));
}
I am not an expert when it comes to RegularExpressions but I doubt it would be useful for this sort of computation.
To me, a simple iteration over the characters of the input is enough:
List<char> specialChars =
new List<char>() { '!', '"', '£', '$', '%', '&', '/', '(', ')', '/', '#' };
string specialString = "#Hi this is rèally/ special strìng!!!";
System.Text.StringBuilder builder =
new System.Text.StringBuilder(specialString.Length);
bool encounteredWhiteSpace = false;
foreach (char ch in specialString)
{
char val = ch;
if (specialChars.Contains(val))
continue;
switch (val)
{
case 'è':
val = 'e'; break;
case 'à':
val = 'a'; break;
case 'ò':
val = 'o'; break;
case 'ù':
case 'ü':
val = 'u'; break;
case 'ı':
case 'ì':
val = 'i'; break;
}
if (val == ' ' || val == '\t')
{
encounteredWhiteSpace = true;
continue;
}
if (encounteredWhiteSpace)
{
builder.Append('-');
encounteredWhiteSpace = false;
}
builder.Append(val);
}
string result = builder.ToString();