-1

The screenshot sums up the problem:

enter image description here

I have no control over the retrieved value. It comes in with some funky format that I can't figure out and the parsing fails even though it looks totally normal. Typing the value in manually works just fine.

How can I "normalize" the retrieved value so Decimal.Parse does not fail?

For reference, here is the string that fails (copied and pasted):

"‎10.00"

tnw
  • 13,521
  • 15
  • 70
  • 111
  • that shouldn't fail to parse – Rahul Jul 17 '17 at 20:11
  • which culture is it of your machine? – Ehsan Sajjad Jul 17 '17 at 20:14
  • 8
    From PowerShell: `"‎10.00".Length` returns `6`. Well well, could there be some sort of hidden character? Yes of course. Your string starts with [`U+200E LEFT-TO-RIGHT MARK`](http://www.fileformat.info/info/unicode/char/200e/index.htm). If your user is supposed to be able to enter that, some kind of normalization may be needed. – Jeroen Mostert Jul 17 '17 at 20:16
  • 1
    Possible duplicate of [Removing hidden characters from within strings](https://stackoverflow.com/questions/15259275/removing-hidden-characters-from-within-strings) – Nate Barbettini Jul 17 '17 at 20:20
  • @Rahul Try it yourself. https://dotnetfiddle.net/pi5xZq – tnw Jul 17 '17 at 20:32

4 Answers4

6

First I would check your regional settings to eliminate anything as simple as a difference in expected decimal separator.

If that draws a blank then if the string 10.00 parses successfully then a string that looks like 10.00 but which fails to parse cannot actually be 10.00.

Inspect and determine the character code of each character of the string and confirm that it really is 10.00 and not some exotic Unicode that has the same appearance but which is actually different (which may also include characters which are not even visible when displayed).

Deltics
  • 22,162
  • 2
  • 42
  • 70
  • The regional settings are fine. It looks like there is a null character at the beginning. `input.Replace("\0", string.Empty);` does not work either. – tnw Jul 17 '17 at 20:24
1

You might have some kind of special character hidden in the string you are retrieving.

Try this:

Double.Parse(Regex.Replace(decimalValue, @"[^0-9.,]+", ""))

You might need to add using statement for System.Text.RegularExpressions

  • This worked! Thank you. Working example: https://dotnetfiddle.net/M1cFWi – tnw Jul 17 '17 at 20:38
  • You are welcome. I forgot to mention I was using this for a variable that would only get positive values. If you are going to receive negative values as well, change your regex to @"[^0-9.,]+-" (note the added -) – Sabrina Fernandez Vazzino Jul 17 '17 at 21:05
  • The @"[^0-9.,]+-" is a nonsense and anyway the whole approach is not a good idea. It changes non-number strings like AW57 into numbers (57) and numbers into different numbers (like 1E7 into 17). It changes the input in rather unpredictable way, making the whole program unreliable. – Antonín Lejsek Jul 17 '17 at 22:11
  • @AntonínLejsek My use case is specific enough where that is not a concern. – tnw Jul 18 '17 at 14:21
  • @SabrinaFernandezVazzino Are you sure about the `+-`? To the best of my knowledge the `+` means "one or more", nothing to do with positive numbers. – tnw Jul 18 '17 at 14:22
  • 1
    Sorry, I meant @"[^0-9.,-]+" – Sabrina Fernandez Vazzino Jul 18 '17 at 15:14
0

I would replace only the one problematic character, that is the safest option:

s = s.Replace("\u200E", "");
Antonín Lejsek
  • 6,003
  • 2
  • 16
  • 18
-1

As Jeroen Mostert mentioned in a comment, there is a non-printed character in your decimalValue.

This is a similar question which should help you deal with that.

https://stackoverflow.com/a/15259355/7636764

Edit:

Using the the string output = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray()); part of the solution, but also include in || char.IsPunctuation(c) after IsDigit will get your desired result.

B. Witter
  • 564
  • 6
  • 19