Remove Currency Character from Currency String in C# [duplicate] - c#

I am using Selenium(C#) on NUnit Framework and is getting a string from UI as $4850.19.
I want to compare above string with the value from backend (DB) to assert they are equal.
I am using a below method to parse my dollar amount from front-end, but the issue is that is also stripping the decimal point; and obviously the comparison with backend is failing.
Method used:
public static string RemoveNonNumeric(string s)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i++)
if (Char.IsNumber(s[i]))
sb.Append(s[i]);
return sb.ToString();
}
How to strip out any '$' or ',' but keep '.' in the value?

With Reg ex it's trivial
Regex.Replace(s, "[^0-9.]", "")

You can also use the decimal.Parse method to parse a string formatted as currency into a decimal type:
string input = "$4,850.19";
decimal result = decimal.Parse(input, NumberStyles.Currency);
Console.WriteLine($"{input} => {result}");
Output:

Another way to do it if you don't want to go the decimal.Parse route is to simply return only numeric and '.' characters from the string:
public static string RemoveNonNumeric2(string s)
{
return string.Concat(s?.Where(c => char.IsNumber(c) || c == '.') ?? "");
}

Thanks for all inputs above, I kind of figured out an easy way to handle this for now (as shown below) -
public static string RemoveNonNumeric(string s)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i++)
if (Char.IsNumber(s[i]) || s[i] == '.')
sb.Append(s[i]);
return sb.ToString();
}
I would like to try other ways of handling this as well soon.

Related

Clean string to have only numbers c#

I want to do have only the numbers from a string. I have tried this:
string phoneNumber = txtPhoneNumber.Text;
string cleanPhoneNumber = string.Empty;
foreach (char c in phoneNumber)
{
if (c.Equals('0') || c.Equals('1') || c.Equals('2') ||
c.Equals('3') || c.Equals('4') || c.Equals('5') ||
c.Equals('6') || c.Equals('7') || c.Equals('8') ||
c.Equals('9'))
cleanPhoneNumber += Convert.ToString(c);
}
The solution above worked, but i want to know if there is a more efficient way.
string b = string.Empty;
for (int i=0; i< a.Length; i++)
{
if (Char.IsDigit(a[i]))
b += a[i];
}
Or use Regex
resultString = Regex.Match(subjectString, #"\d+").Value;
Since you, probable, want digits in 0..9 range only, not all unicode ones (which include Persian, Indian digits etc.), char.IsDigit and \d regular expression are not exact solutions.
Linq:
string cleanPhoneNumber = string.Concat(phoneNumber.Where(c => c >= '0' && c <= '9'));
Regex:
either Sami's, integer's codes or
resultString = Regex.Match(subjectString, #"\d+", RegexOptions.ECMAScript ).Value;
which is Krystian Borysewicz's solution with ECMAScript option to be on the safe side.
string phoneNumber = txtPhoneNumber.Text;
// Get numbers only
Regex numbersRegex = new Regex("[^0-9]");
var cleanPhoneNumber = numbersRegex.Replace(phoneNumber, ""));
If you're looking to be efficient in terms on time then you should avoid using regex as the Regex class will need to parse your expression before it applies it to the phone number.
The code below avoid regex and keeps memory allocations to a minimum. It only allocates twice, once for a buffer to store the numbers and the once again at the end to create the string containing the valid numbers.
string Clean(string text)
{
var validCharacters = new char[text.Length];
var next = 0;
for(int i = 0; i < text.Length; i++)
{
char c = text[i];
if(char.IsDigit(c))
{
validCharacters[next++] = c;
}
}
return new string(validCharacters, 0, next);
}
using Linq:
string cleanPhoneNumber = new String(phoneNumber.Where(Char.IsDigit).ToArray());

Convert Dash-Separated String to camelCase via C#

I have a large XML file that contain tag names that implement the dash-separated naming convention. How can I use C# to convert the tag names to the camel case naming convention?
The rules are:
1. Convert all characters to lower case
2. Capitalize the first character after each dash
3. Remove all dashes
Example
Before Conversion
<foo-bar>
<a-b-c></a-b-c>
</foo-bar>
After Conversion
<fooBar>
<aBC></aBC>
</fooBar>
Here's a code example that works, but it's slow to process - I'm thinking that there is a better way to accomplish my goal.
string ConvertDashToCamelCase(string input)
{
input = input.ToLower();
char[] ca = input.ToCharArray();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < ca.Length; i++)
{
if(ca[i] == '-')
{
string t = ca[i + 1].ToString().toUpper();
sb.Append(t);
i++;
}
else
{
sb.Append(ca[i].ToString());
}
}
return sb.ToString();
}
The reason your original code was slow is because you're calling ToString all over the place unnecessarily. There's no need for that. There's also no need for the intermediate array of char. The following should be much faster, and faster than the version that uses String.Split, too.
string ConvertDashToCamelCase(string input)
{
StringBuilder sb = new StringBuilder();
bool caseFlag = false;
for (int i = 0; i < input.Length; ++i)
{
char c = input[i];
if (c == '-')
{
caseFlag = true;
}
else if (caseFlag)
{
sb.Append(char.ToUpper(c));
caseFlag = false;
}
else
{
sb.Append(char.ToLower(c));
}
}
return sb.ToString();
}
I'm not going to claim that the above is the fastest possible. In fact, there are several obvious optimizations that could save some time. But the above is clean and clear: easy to understand.
The key is the caseFlag, which you use to indicate that the next character copied should be set to upper case. Also note that I don't automatically convert the entire string to lower case. There's no reason to, since you'll be looking at every character anyway and can do the appropriate conversion at that time.
The idea here is that the code doesn't do any more work than it absolutely has to.
For completeness, here's also a regular expression one-liner (inspred by this JavaScript answer):
string ConvertDashToCamelCase(string input) =>
Regex.Replace(input, "-.", m => m.Value.ToUpper().Substring(1));
It replaces all occurrences of -x with x converted to upper case.
Special cases:
If you want lower-case all other characters, replace input with input.ToLower() inside the expression:
string ConvertDashToCamelCase(string input) =>
Regex.Replace(input.ToLower(), "-.", m => m.Value.ToUpper().Substring(1));
If you want to support multiple dashes between words (dash--case) and have all of the dashes removed (dashCase), replace - with -+ in the regular expression (to greedily match all sequences of dashes) and keep only the final character:
string ConvertDashToCamelCase(string input) =>
Regex.Replace(input, "-+.", m => m.Value.ToUpper().Substring(m.Value.Length - 1));
If you want to support multiple dashes between words (dash--case) and remove only the final one (dash-Case), change the regular expression to match only a dash followed by a non-dash (rather than a dash followed by any character):
string ConvertDashToCamelCase(string input) =>
Regex.Replace(input, "-[^-]", m => m.Value.ToUpper().Substring(1));
string ConvertDashToCamelCase(string input)
{
string[] words = input.Split('-');
words = words.Select(element => wordToCamelCase(element));
return string.Join("", words);
}
string wordToCamelCase(string input)
{
return input.First().ToString().ToUpper() + input.Substring(1).ToLower();
}
Here is an updated version of #Jim Mischel's answer that will ignore the content - i.e. it will only camelCase tag names.
string ConvertDashToCamelCase(string input)
{
StringBuilder sb = new StringBuilder();
bool caseFlag = false;
bool tagFlag = false;
for(int i = 0; i < input.Length; i++)
{
char c = input[i];
if(tagFlag)
{
if (c == '-')
{
caseFlag = true;
}
else if (caseFlag)
{
sb.Append(char.ToUpper(c));
caseFlag = false;
}
else
{
sb.Append(char.ToLower(c));
}
}
else
{
sb.Append(c);
}
// Reset tag flag if necessary
if(c == '>' || c == '<')
{
tagFlag = (c == '<');
}
}
return sb.ToString();
}
using System;
using System.Text;
public class MyString
{
public static string ToCamelCase(string str)
{
char[] s = str.ToCharArray();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.Length; i++)
{
if (s[i] == '-' || s[i] == '_')
sb.Append(Char.ToUpper(s[++i]));
else
sb.Append(s[i]);
}
return sb.ToString();
}
}

How to remove leading zeros using C#

How to remove leading zeros in strings using C#?
For example in the following numbers, I would like to remove all the leading zeros.
0001234
0000001234
00001234
This is the code you need:
string strInput = "0001234";
strInput = strInput.TrimStart('0');
It really depends on how long the NVARCHAR is, as a few of the above (especially the ones that convert through IntXX) methods will not work for:
String s = "005780327584329067506780657065786378061754654532164953264952469215462934562914562194562149516249516294563219437859043758430587066748932647329814687194673219673294677438907385032758065763278963247982360675680570678407806473296472036454612945621946";
Something like this would
String s ="0000058757843950000120465875468465874567456745674000004000".TrimStart(new Char[] { '0' } );
// s = "58757843950000120465875468465874567456745674000004000"
Code to avoid returning an empty string ( when input is like "00000").
string myStr = "00012345";
myStr = myStr.TrimStart('0');
myStr = myStr.Length > 0 ? myStr : "0";
return numberString.TrimStart('0');
Using the following will return a single 0 when input is all 0.
string s = "0000000"
s = int.Parse(s).ToString();
TryParse works if your number is less than Int32.MaxValue. This also gives you the opportunity to handle badly formatted strings. Works the same for Int64.MaxValue and Int64.TryParse.
int number;
if(Int32.TryParse(nvarchar, out number))
{
// etc...
number.ToString();
}
This Regex let you avoid wrong result with digits which consits only from zeroes "0000" and work on digits of any length:
using System.Text.RegularExpressions;
/*
00123 => 123
00000 => 0
00000a => 0a
00001a => 1a
00001a => 1a
0000132423423424565443546546356546454654633333a => 132423423424565443546546356546454654633333a
*/
Regex removeLeadingZeroesReg = new Regex(#"^0+(?=\d)");
var strs = new string[]
{
"00123",
"00000",
"00000a",
"00001a",
"00001a",
"0000132423423424565443546546356546454654633333a",
};
foreach (string str in strs)
{
Debug.Print(string.Format("{0} => {1}", str, removeLeadingZeroesReg.Replace(str, "")));
}
And this regex will remove leading zeroes anywhere inside string:
new Regex(#"(?<!\d)0+(?=\d)");
// "0000123432 d=0 p=002 3?0574 m=600"
// => "123432 d=0 p=2 3?574 m=600"
Regex rx = new Regex(#"^0+(\d+)$");
rx.Replace("0001234", #"$1"); // => "1234"
rx.Replace("0001234000", #"$1"); // => "1234000"
rx.Replace("000", #"$1"); // => "0" (TrimStart will convert this to "")
// usage
var outString = rx.Replace(inputString, #"$1");
I just crafted this as I needed a good, simple way.
If it gets to the final digit, and if it is a zero, it will stay.
You could also use a foreach loop instead for super long strings.
I just replace each leading oldChar with the newChar.
This is great for a problem I just solved, after formatting an int into a string.
/* Like this: */
int counterMax = 1000;
int counter = ...;
string counterString = counter.ToString($"D{counterMax.ToString().Length}");
counterString = RemoveLeadingChars('0', ' ', counterString);
string fullCounter = $"({counterString}/{counterMax})";
// = ( 1/1000) ... ( 430/1000) ... (1000/1000)
static string RemoveLeadingChars(char oldChar, char newChar, char[] chars)
{
string result = "";
bool stop = false;
for (int i = 0; i < chars.Length; i++)
{
if (i == (chars.Length - 1)) stop = true;
if (!stop && chars[i] == oldChar) chars[i] = newChar;
else stop = true;
result += chars[i];
}
return result;
}
static string RemoveLeadingChars(char oldChar, char newChar, string text)
{
return RemoveLeadingChars(oldChar, newChar, text.ToCharArray());
}
I always tend to make my functions suitable for my own library, so there are options.

Fastest way to remove white spaces in string

I'm trying to fetch multiple email addresses seperated by "," within string from database table, but it's also returning me whitespaces, and I want to remove the whitespace quickly.
The following code does remove whitespace, but it also becomes slow whenever I try to fetch large number email addresses in a string like to 30000, and then try to remove whitespace between them. It takes more than four to five minutes to remove those spaces.
Regex Spaces =
new Regex(#"\s+", RegexOptions.Compiled);
txtEmailID.Text = MultipleSpaces.Replace(emailaddress),"");
Could anyone please tell me how can I remove the whitespace within a second even for large number of email address?
I would build a custom extension method using StringBuilder, like:
public static string ExceptChars(this string str, IEnumerable<char> toExclude)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (!toExclude.Contains(c))
sb.Append(c);
}
return sb.ToString();
}
Usage:
var str = s.ExceptChars(new[] { ' ', '\t', '\n', '\r' });
or to be even faster:
var str = s.ExceptChars(new HashSet<char>(new[] { ' ', '\t', '\n', '\r' }));
With the hashset version, a string of 11 millions of chars takes less than 700 ms (and I'm in debug mode)
EDIT :
Previous code is generic and allows to exclude any char, but if you want to remove just blanks in the fastest possible way you can use:
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
case ' ':
continue;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
EDIT 2 :
as correctly pointed out in the comments, the correct way to remove all the blanks is using char.IsWhiteSpace method :
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if(!char.IsWhiteSpace(c))
sb.Append(c);
}
return sb.ToString();
}
Given the implementation of string.Replaceis written in C++ and part of the CLR runtime I'm willing to bet
email.Replace(" ","").Replace("\t","").Replace("\n","").Replace("\r","");
will be the fastest implementation. If you need every type of whitespace, you can supply the hex value the of unicode equivalent.
With linq you can do it simply:
emailaddress = new String(emailaddress
.Where(x=>x!=' ' && x!='\r' && x!='\n')
.ToArray());
I didn't compare it with stringbuilder approaches, but is much more faster than string based approaches.
Because it does not create many copy of strings (string is immutable and using it directly causes to dramatically memory and speed problems), so it's not going to use very big memory and not going to slow down the speed (except one extra pass through the string at first).
You should try String.Trim(). It will trim all spaces from start to end of a string
Or you can try this method from linked topic: [link]
public static unsafe string StripTabsAndNewlines(string s)
{
int len = s.Length;
char* newChars = stackalloc char[len];
char* currentChar = newChars;
for (int i = 0; i < len; ++i)
{
char c = s[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
continue;
default:
*currentChar++ = c;
break;
}
}
return new string(newChars, 0, (int)(currentChar - newChars));
}
emailaddress.Replace(" ", string.Empty);
There are many diffrent ways, some faster then others:
public static string StripTabsAndNewlines(this string str) {
//string builder (fast)
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++) {
if ( ! Char.IsWhiteSpace(s[i])) {
sb.Append();
}
}
return sb.tostring();
//linq (faster ?)
return new string(str.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray());
//regex (slow)
return Regex.Replace(str, #"\s+", "")
}
Please use the TrimEnd() method of the String class. You can find a great example here.
You should consider replacing spaces on the record-set within your stored procedure or query using the REPLACE( ) function if possible & even better fix your DB records since a space in an email address is invalid anyways.
As mentioned by others you would need to profile the different approaches. If you are using Regex you should minimally make it a class-level static variable:
public static Regex MultipleSpaces = new Regex(#"\s+", RegexOptions.Compiled);
emailAddress.Where(x=>{ return x != ' ';}).ToString( ) is likely to have function overhead although it could be optimized to inline by Microsoft -- again profiling will give you the answer.
The most efficient method would be to allocate a buffer and copy character by character to a new buffer and skip the spaces as you do that. C# does support pointers so you could use unsafe code, allocate a raw buffer and use pointer arithmetic to copy just like in C and that is as fast as this can possibly be done. The REPLACE( ) in SQL will handle it like that for you.
string str = "Hi!! this is a bunch of text with spaces";
MessageBox.Show(new String(str.Where(c => c != ' ').ToArray()));
I haven't done performance testing on this, but it's simpler than most of the other answers.
var s1 = "\tstring \r with \t\t \nwhitespace\r\n";
var s2 = string.Join("", s1.Split());
The result is
stringwithwhitespace
string input =Yourinputstring;
string[] strings = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string value in strings)
{
string newv= value.Trim();
if (newv.Length > 0)
newline += value + "\r\n";
}
string s = " Your Text ";
string new = s.Replace(" ", string.empty);
// Output:
// "YourText"
Fastest and general way to do this (line terminators, tabs will be processed as well). Regex powerful facilities don't really needed to solve this problem, but Regex can decrease performance.
new string
(stringToRemoveWhiteSpaces
.Where
(
c => !char.IsWhiteSpace(c)
)
.ToArray<char>()
)

Format string with dashes

I have a compressed string value I'm extracting from an import file. I need to format this into a parcel number, which is formatted as follows: ##-##-##-###-###. So therefore, the string "410151000640" should become "41-01-51-000-640". I can do this with the following code:
String.Format("{0:##-##-##-###-###}", Convert.ToInt64("410151000640"));
However, The string may not be all numbers; it could have a letter or two in there, and thus the conversion to the int will fail. Is there a way to do this on a string so every character, regardless of if it is a number or letter, will fit into the format correctly?
Regex.Replace("410151000640", #"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5");
Or the slightly shorter version
Regex.Replace("410151000640", #"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5");
I would approach this by having your own formatting method, as long as you know that the "Parcel Number" always conforms to a specific rule.
public static string FormatParcelNumber(string input)
{
if(input.length != 12)
throw new FormatException("Invalid parcel number. Must be 12 characters");
return String.Format("{0}-{1}-{2}-{3}-{4}",
input.Substring(0,2),
input.Substring(2,2),
input.Substring(4,2),
input.Substring(6,3),
input.Substring(9,3));
}
This should work in your case:
string value = "410151000640";
for( int i = 2; i < value.Length; i+=3){
value = value.Insert( i, "-");
}
Now value contains the string with dashes inserted.
EDIT
I just now saw that you didn't have dashes between every second number all the way, to this will require a small tweak (and makes it a bit more clumsy also I'm afraid)
string value = "410151000640";
for( int i = 2; i < value.Length-1; i+=3){
if( value.Count( c => c == '-') >= 3) i++;
value = value.Insert( i, "-");
}
If its part of UI you can use MaskedTextProvider in System.ComponentModel
MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa");
prov.Set("41x151000a40");
string result = prov.ToDisplayString();
Here is a simple extension method with some utility:
public static string WithMask(this string s, string mask)
{
var slen = Math.Min(s.Length, mask.Length);
var charArray = new char[mask.Length];
var sPos = s.Length - 1;
for (var i = mask.Length - 1; i >= 0 && sPos >= 0;)
if (mask[i] == '#') charArray[i--] = s[sPos--];
else
charArray[i] = mask[i--];
return new string(charArray);
}
Use it as follows:
var s = "276000017812008";
var mask = "###-##-##-##-###-###";
var dashedS = s.WithMask(mask);
You can use it with any string and any character other than # in the mask will be inserted. The mask will work from right to left. You can tweak it to go the other way if you want.
Have fun.
If i understodd you correctly youre looking for a function that removes all letters from a string, aren't you?
I have created this on the fly, maybe you can convert it into c# if it's what you're looking for:
Dim str As String = "410151000vb640"
str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str)))
Public Function MakeNumber(ByVal stringInt As String) As String
Dim sb As New System.Text.StringBuilder
For i As Int32 = 0 To stringInt.Length - 1
If Char.IsDigit(stringInt(i)) Then
sb.Append(stringInt(i))
End If
Next
Return sb.ToString
End Function

Categories

Resources