I have some customized string formats of double values. I need to convert these strings to double values at some point (Note that these strings may contain error messages other than numbers). So I first check if these strings are numbers, and if yes, then convert them to double. Isnumeric works for my first customized string format. But I found that is numeric cannot recognize percentage strings. I wonder why isnumeric understands () but cannot understand %. And what is the better way to convert "(100.00)" and "50%" to doubles other than Cdbl?

Well, I was bored, so I figured I'd start working on some code that would work in all cultures. If you need code now, though, I'd be happy to write some up that works in yours.
–
Timiz0rFeb 16 '12 at 15:28

4 Answers
4

First, IsNumeric and C<whatever> generally aren't used because they can provide unexpected outputs. Typically you would use Double.TryParse or Convert.ToDouble (or whatever type) because they reliably parses numbers as you would expect; you just have to make sure it's in the right format.

Also, those methods are more efficient because you can determine if a string is a number and parse it all in one go. Just note that Parse and Convert throw exceptions when the format is wrong.

Now, as far as I know, there's know built-in way convert from percent notation. I went ahead and wrote three methods (current culture, any culture, invariant culture) that tested fine with 0.5 and -0.5 on the four possible locations of the percent symbol.

'these will return Double.NaN if they fails
'this parses based on the current culture
Public Function ParseDoublePercent(ByVal input As String) As Double
Return ParseDoublePercent(input, System.Globalization.NumberFormatInfo.CurrentInfo)
End Function
'invariant culture
Public Function ParseDoublePercentInvariant(ByVal input As String) As Double
Return ParseDoublePercent(input, System.Globalization.NumberFormatInfo.InvariantInfo)
End Function
'this parses based on a specified culture
Public Function ParseDoublePercent(ByVal input As String, ByVal provider As IFormatProvider) As Double
If String.IsNullOrEmpty(input) OrElse input.Length < 3 Then Return Double.NaN 'minimum length of string is 2 (0%)
'get some information about how the percent should be formatted
Dim format As System.Globalization.NumberFormatInfo = System.Globalization.NumberFormatInfo.GetInstance(provider)
'how this will be parsed will first depend on if it's positive or negative
Dim isNegative As Boolean = input.Substring(0, 1) = "-"
Dim percentPattern As Integer = If(isNegative, format.PercentNegativePattern, format.PercentPositivePattern)
'i'm using convert.todouble because I don't want to use NumberStyles in Double.TryParse
Try
Select Case percentPattern
Case 0 'n %, such as -50.00 %, 50.00 %
Return Convert.ToDouble(
input.Replace(" " & format.PercentSymbol, "e-" & format.PercentDecimalDigits),
provider)
Case 1 'n%, such as -50.00%, 50.00%
Return Convert.ToDouble(
input.Replace(format.PercentSymbol, "e-" & format.PercentDecimalDigits),
provider)
Case 2 '%n, such as -%50.00, %50.00
'need to do some special parsing just in case there are incorrect percent signs in the middle of the number
'dont want to just replace all of them
Return Convert.ToDouble(
input.Remove(If(isNegative, 1, 0), 1) & "e-" & format.PercentDecimalDigits, provider)
Case 3 '% n, such as '%-50.00, % 50.00
Return Convert.ToDouble(input.Remove(0, 1) & "e-" & format.PercentDecimalDigits, provider)
Case Else
Return Double.NaN 'should not happen
End Select
Catch ex As FormatException 'an exception is thrown when the string fails to parse
Return Double.NaN
End Try
End Function

isnumeric returns a Boolean value indicating whether an expression can be evaluated as a number. In your case % is not a number, so the error. Try the following code.

If isnumeric(str2.Substring(0,str2.length-2))

IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort, or an Object that contains one of those numeric types. It also returns True if Expression is a Char or String that can be successfully converted to a number.

IsNumeric returns False if Expression is of data type Date or of data type Object and it does not contain a numeric type. IsNumeric returns False if Expression is a Char or String that cannot be converted to a number.