3

I'm using Str.regexp, I want to know how to check if undetermined length string contains only number characters.

This is what I'm doing:

Str.string_match "[0-9]+" "1212df3124" 0;;

The problem is it evaluates to true, but it should returns false because it contains 'df' substring. (This is not the same as C# regexp, it's Ocaml)

Erik Godard
  • 5,930
  • 6
  • 30
  • 33
dantopa
  • 51
  • 1
  • 4

2 Answers2

3

The Str.string_match function checks whether the pattern matches starting at the index you supply. As long as there's at least one digit at the beginning of the string, your pattern will match. If the string starts with something other than a digit, your pattern will fail to match:

# Str.string_match (Str.regexp "[0-9]+") "df3124" 0;;
- : bool = false

To check against the whole string, you need to "anchor" the pattern to the end with $. I.e., you need to make sure the match goes to the end of the string.

# Str.string_match (Str.regexp "[0-9]+") "1212df3124" 0;;
- : bool = true
# Str.string_match (Str.regexp "[0-9]+$") "1212df3124" 0;;
- : bool = false
# Str.string_match (Str.regexp "[0-9]+$") "3141592" 0;;
- : bool = true
# Str.string_match (Str.regexp "[0-9]+$") "" 0;;
- : bool = false
Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
1

Another solutions is to use int_of_string to see if it raises an exception:

let check_str s = 
  try int_of_string s |> ignore; true
  with Failure _ -> false

If you are going to convert your string to an integer anyway, you can use that.

Beware, it will allow everything that OCaml's parser consider to be an integer

check_str "10";;   //gives true
check_str "0b10";; //gives true, 0b11 = 2
check_str "0o10";; //gives true, 0o10 = 8
check_str "0x10";; //gives true, 0x10 = 16

So if you want to allow only decimal representation you can do:

let check_str s = 
  try (int_of_string s |> string_of_int) = s
  with Failure _ -> false

as string_of_int returns the string representation of an integer, in decimal.

ghilesZ
  • 1,502
  • 1
  • 18
  • 30