답변:
Integer.parse/1
이상은 String.to_integer/1
?
Integer.parse/1
은 :error
실패 하면 원자를 반환합니다 . String.to_integer/1
던졌습니다 (FunctionClauseError)
.
받는 사람뿐만 아니라 Integer.parse/1
와 Float.parse/1
호세 당신도 확인할 수 있습니다 제안 기능 String.to_integer/1
및String.to_float/1
.
힌트 : 참조 to_atom/1
, to_char_list/1
, to_existing_atom/1
다른 변환을 위해.
이 페이지의 사람들에게 감사드립니다. 여기에 답변을 단순화하십시오.
{intVal, ""} = Integer.parse(val)
전체 문자열이 (단지 접두사가 아닌) 구문 분석되었는지 확인합니다.
문자열에서 숫자를 생성하는 4 가지 함수가 있습니다.
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
로 String.to_float
: 만 예를 들어 잘 형식의 부동 소수점 처리 할 수 있습니다 1.0
,하지 1
(정수). 즉에 설명 된 String.to_float
의 문서
텍스트 표현이 문자열 인 부동 소수점을 반환합니다.
string은 소수점을 포함하는 부동 소수점의 문자열 표현이어야합니다. 소수점이없는 문자열을 float로 구문 분석하려면 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
튜플에서 첫 번째 요소를 가져 오는 데 사용 하면 더 짧고 달콤합니다.
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]
char_list로 변환 한 다음 Erlang to_integer/1
또는 to_float/1
.
예
iex> {myInt, _} = :string.to_integer(to_char_list("23"))
{23, []}
iex> myInt
23
fn q -> {v, _} = Float.parse(q); v end
내가 싫어하는 것입니다. Enum.map
예를 들어 에서 사용하고 list |> Enum.map(&String.to_float/1)
싶지만 string.to_float가 정수에 대해 작동하지 않습니까?
Decimal.new("1") |> Decimal.to_integer
Decimal.new("1.0") |> Decimal.to_float
사용의 문제 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
^[0-9]*$
사용 사례에 따라 정규 표현식이 더 간단 할 수 있습니다 (예 :) .
문자열을 문자열 내에있는 숫자 유형으로 변환하고 다른 모든 문자를 제거하려면 과잉 일 수 있지만 float이면 float를 반환하고 int이면 int를 반환하고 문자열에 포함되지 않으면 nil을 반환합니다. 숫자 유형.
@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)
String.to_integer/1