0

I simply just want a function or way to check if a string contains the numbers 0-9. The code below is what I found from another thread but when I test with string "1" the output is still false.

let numbercheck x = box x :? int

Julian
  • 17
  • 2
  • It's not clear what you're looking for. What should the function return for a string like `"1a2b3c"`, which contains a mixture of digits and other characters? Are you trying to parse the string as a number? – Brian Berns May 08 '22 at 17:47
  • Checking if a string contains a single number character (1, 2, 3) is trivial, are you curious to see if the number is an `int` or `float` per your question title? – LSM07 May 08 '22 at 17:54

3 Answers3

1

There are several options:

open System

let numbercheck (candidate : string) =
  let isInt, _ = Int32.TryParse candidate
  let isDouble, _ = Double.TryParse candidate
  isInt || isDouble

(a more efficient version without needlessly calculating isDouble is left as an exercise to the reader)

open System

let numbercheck (candidate : string) =
  candidate |> Seq.forall Char.IsDigit

(change to Seq.exists to detect digits within other chars) or regex (see other answer)…

CaringDev
  • 8,391
  • 1
  • 24
  • 43
0

One simple way to check whether number is inside string is to use regular expressions:

open System.Text.RegularExpressions

let containsNumber str =
    Regex.IsMatch(str, @"[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)")

containsNumber "123" |> printfn "%b" // true
containsNumber "asd" |> printfn "%b" // false
containsNumber "asd123" |> printfn "%b" // true
containsNumber "asd123." |> printfn "%b" // true
containsNumber "asd123.0" |> printfn "%b" // true
containsNumber "a123.0sd" |> printfn "%b" // true

This regex is taken from answer https://stackoverflow.com/a/12643073/10339675

JL0PD
  • 3,698
  • 2
  • 15
  • 23
  • While this is the accepted answer it's not the simplest and certainly not the fastest. Instead check if any character in the string is a digit: `let hasNumber x = (x:string) |> Seq.exists System.Char.IsDigit` – Peheje May 12 '22 at 20:12
0

There is a difference, when you just want to know, whether the string contains a number or you want to do something with the numeric value.

If you just want to check the string contains a number:

open System.Text.RegularExpressions

let containsNumber (string: string) =
    match string |> Int32.TryParse with
    | true, _int -> true                   // this will parse a string if it contains just an int value
    | _ ->
    match string |> Double.TryParse with   // this will parse a string if it contains just an float value
    | true, _float -> true
    | _ -> Regex.IsMatch(string, @"[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)") // this will check, if the string contains numbers (amongst other characters)

containsNumber "" |> printfn "%b"          // false - by regex match
containsNumber "123" |> printfn "%b"       // true - by int parse
containsNumber "13.37" |> printfn "%b"     // true - by float parse
containsNumber "ab12cd" |> printfn "%b"    // true - by regex match
containsNumber "ab12.3cd" |> printfn "%b"  // true - by regex match
containsNumber "1a2b3c" |> printfn "%b"    // true - by regex match

The regex is taken from previous answer https://stackoverflow.com/a/72166297/19068406

If you want to actually use the parsed value, it could be a bit more complicated for the case with the regex, but it is fairly easy with the first and second option, since you just use the parsed value.

type IntOrFloat =
    | Int of int
    | Float of float

let containsIntOrFloat (string: string) =
    match string |> Int32.TryParse with
    | true, int -> Some (Int int)
    | _ ->
    match string |> Double.TryParse with
    | true, float -> Some (Float float)
    | _ -> None

containsIntOrFloat "" |> printfn "%A"         // None
containsIntOrFloat "123" |> printfn "%A"      // Some (Int 123)
containsIntOrFloat "13.37" |> printfn "%A"    // Some (Float 13.37)
containsIntOrFloat "ab12cd" |> printfn "%A"   // None
containsIntOrFloat "ab12.3cd" |> printfn "%A" // None
containsIntOrFloat "1a2b3c" |> printfn "%A"   // None