Ben*_*kin 79
我更喜欢snrobot的答案.对于这个简单的用例,使用Java方法比使用read-string更简单,更健壮.我确实做了一些小改动.由于作者没有排除负数,我调整它以允许负数.我也这样做了它需要数字从字符串的开头开始.
(defn parse-int [s]
(Integer/parseInt (re-find #"\A-?\d+" s)))
Run Code Online (Sandbox Code Playgroud)
另外,我发现Integer/parseInt在没有给出基数的情况下解析为十进制,即使有前导零也是如此.
首先,解析一个整数(因为这是谷歌的一个命中,它是很好的背景信息):
你可以使用读者:
(read-string "9") ; => 9
Run Code Online (Sandbox Code Playgroud)
您可以在阅读后检查它是否为数字:
(defn str->int [str] (if (number? (read-string str))))
Run Code Online (Sandbox Code Playgroud)
我不确定clojure读者是否可以信任用户输入,因此您可以在读取之前进行检查:
(defn str->int [str] (if (re-matches (re-pattern "\\d+") str) (read-string str)))
Run Code Online (Sandbox Code Playgroud)
我想我更喜欢最后的解决方案.
现在,针对您的具体问题.要解析以整数开头的内容,例如29px
:
(read-string (second (re-matches (re-pattern "(\\d+).*") "29px"))) ; => 29
Run Code Online (Sandbox Code Playgroud)
小智 77
这将适用于10px
或px10
(defn parse-int [s]
(Integer. (re-find #"\d+" s )))
Run Code Online (Sandbox Code Playgroud)
它只解析第一个连续数字
user=> (parse-int "10not123")
10
user=> (parse-int "abc10def11")
10
Run Code Online (Sandbox Code Playgroud)
May*_*iel 29
(defn parse-int [s]
(Integer. (re-find #"[0-9]*" s)))
user> (parse-int "10px")
10
user> (parse-int "10")
10
Run Code Online (Sandbox Code Playgroud)
小智 16
这对我来说很复杂,更直截了当.
(读取字符串"123")
=> 123
AFAIK没有针对您的问题的标准解决方案.我认为以下类似的东西clojure.contrib.str-utils2/replace
应该有所帮助:
(defn str2int [txt]
(Integer/parseInt (replace txt #"[a-zA-Z]" "")))
Run Code Online (Sandbox Code Playgroud)
这不是完美的,但这里有一些东西filter
,Character/isDigit
和Integer/parseInt
.它对浮点数不起作用,如果输入中没有数字则失败,所以你应该清理它.我希望有一个更好的方法来做到这一点,不涉及这么多的Java.
user=> (defn strToInt [x] (Integer/parseInt (apply str (filter #(Character/isDigit %) x))))
#'user/strToInt
user=> (strToInt "45px")
45
user=> (strToInt "45")
45
user=> (strToInt "a")
java.lang.NumberFormatException: For input string: "" (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)
对于任何其他希望将更普通的字符串文字解析为数字(即不包含其他非数字字符的字符串)的人。这是两种最好的方法:
使用 Java 互操作:
(Long/parseLong "333")
(Float/parseFloat "333.33")
(Double/parseDouble "333.3333333333332")
(Integer/parseInt "-333")
(Integer/parseUnsignedInt "333")
(BigInteger. "3333333333333333333333333332")
(BigDecimal. "3.3333333333333333333333333332")
(Short/parseShort "400")
(Byte/parseByte "120")
Run Code Online (Sandbox Code Playgroud)
当这对您的用例很重要时,这可以让您精确控制要解析数字的类型。
使用 Clojure EDN 阅读器:
(require '[clojure.edn :as edn])
(edn/read-string "333")
Run Code Online (Sandbox Code Playgroud)
与 using read-string
from不同clojure.core
,using from 在不受信任的输入上使用是不安全的,而edn/read-string
在不受信任的输入(例如用户输入)上运行是安全的。
如果您不需要对类型进行特定控制,这通常比 Java 互操作更方便。它可以解析 Clojure 可以解析的任何数字文字,例如:
;; Ratios
(edn/read-string "22/7")
;; Hexadecimal
(edn/read-string "0xff")
Run Code Online (Sandbox Code Playgroud)
完整列表: https: //www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
扩展 snrobot 的答案:
(defn string->integer [s]
(when-let [d (re-find #"-?\d+" s)] (Integer. d)))
Run Code Online (Sandbox Code Playgroud)
如果输入中没有数字,此版本将返回 nil,而不是引发异常。
我的问题是是否可以将名称缩写为“str->int”,或者是否应该始终完全指定这样的内容。
归档时间: |
|
查看次数: |
75433 次 |
最近记录: |