将长生不老药字符串转换为整数或浮动

我需要将字符串转换为浮点值或整数,

string_to_integer
99658 次浏览

可以将其转换为 char _ list,然后使用 Erlang to_integer/1to_float/1

例如。

iex> {myInt, _} = :string.to_integer(to_char_list("23"))
{23, []}


iex> myInt
23

除了 Integer.parse/1Float.parse/1的功能,何塞建议你也可以检查 String.to_integer/1String.to_float/1

提示: 其他转换请参见 to_atom/1to_char_list/1to_existing_atom/1

感谢本页的朋友们,这里只是简单地回答一个问题:

{int_val, ""} = Integer.parse(val)

因为它验证整个字符串已被解析(而不仅仅是前缀)。

如果你想把一个字符串转换成字符串中的任何数值类型并删除所有其他字符,这可能有点过分,但是如果它是一个浮点数,那么返回一个浮点数; 如果它是一个整型数,那么返回一个浮点数; 如果它不包含数值类型,那么返回一个整型数或者零。

@spec string_to_numeric(binary()) :: float() | number() | nil
def string_to_numeric(val) when is_binary(val), do: _string_to_numeric(Regex.replace(~r{[^\d\.]}, val, ""))
defp _string_to_numeric(val) when is_binary(val), do: _string_to_numeric(Integer.parse(val), val)
defp _string_to_numeric(:error, _val), do: nil
defp _string_to_numeric({num, ""}, _val), do: num
defp _string_to_numeric({num, ".0"}, _val), do: num
defp _string_to_numeric({_num, _str}, val), do: elem(Float.parse(val), 0)

使用 Integer.parse/1的问题是,只要字符串在尾端,就会解析它的任何非数字部分。例如:

Integer.parse("01") # {1, ""}
Integer.parse("01.2") # {1, ".2"}
Integer.parse("0-1") # {0, "-1"}
Integer.parse("-01") # {-1, ""}
Integer.parse("x-01") # :error
Integer.parse("0-1x") # {0, "-1x"}

同样,String.to_integer/1的结果如下:

String.to_integer("01") # 1
String.to_integer("01.2") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2")
String.to_integer("0-1") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2")
String.to_integer("-01") # -1
String.to_integer("x-01") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2")
String.to_integer("0-1x") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2")

相反,应该首先验证字符串。

re = Regex.compile!("^[+-]?[0-9]*\.?[0-9]*$")
Regex.match?(re, "01") # true
Regex.match?(re, "01.2") # true
Regex.match?(re, "0-1") # false
Regex.match?(re, "-01") # true
Regex.match?(re, "x-01") # false
Regex.match?(re, "0-1x") # false

The regular expression could be simpler (e.g. ^[0-9]*$) depending on your use case.

有4个函数从字符串创建数字

  • To _ int,String.to _ float
  • Integer.parse,Float.parse

String.to_integer运行良好,但 String.to_float更为严格:

iex()> "1 2 3 10 100" |> String.split |> Enum.map(&String.to_integer/1)
[1, 2, 3, 10, 100]


iex()> "1.0 1 3 10 100" |> String.split |> Enum.map(&String.to_float/1)
** (ArgumentError) argument error
:erlang.binary_to_float("1")
(elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2

As String.to_float can only handle well-formatted float, e.g: 1.0, not 1 (integer). That was documented in String.to_float's doc

返回文本表示为字符串的浮点数。

字符串必须是包含小数点的浮点数的字符串表示形式。为了解析没有小数点的字符串作为浮点数,应该使用 Float.parse/1。否则,将引发 ArgumentError。

但是 Float.parse返回一个由2个元素组成的元组,而不是您想要的数字,因此将其放入管道并不“酷”:

iex()> "1.0 1 3 10 100" |> String.split \
|> Enum.map(fn n -> {v, _} = Float.parse(n); v end)


[1.0, 1.0, 3.0, 10.0, 100.0]

使用 elem从 tuple 中获取第一个元素,可以使它更短更好:

iex()> "1.0 1 3 10 100" |> String.split \
|> Enum.map(fn n -> Float.parse(n) |> elem(0) end)


[1.0, 1.0, 3.0, 10.0, 100.0]
Decimal.new("1") |> Decimal.to_integer
Decimal.new("1.0") |> Decimal.to_float