如何检查字符串是否为 Scala 中的十进制数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9938098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check to see if a string is a decimal number in Scala
提问by PlexQ
I'm still fairly new to Scala, and I'm discovering new and interesting ways for doing things on an almost daily basis, but they're not always sensible, and sometimes already exist within the language as a construct and I just don't know about them. So, with that preamble, I'm checking to see if a given string is comprised entirely of digits, so I'm doing:
我对 Scala 还是很陌生,我几乎每天都在发现新的有趣的做事方式,但它们并不总是明智的,有时已经作为一种结构存在于语言中,而我只是不这样做'不知道他们。因此,通过该序言,我正在检查给定的字符串是否完全由数字组成,因此我正在执行以下操作:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
is this sensible or just needlessly silly? It there a better way? Is it better just to call x.toInt and catch the exception, or is that less idiomatic? Is there a performance benefit/drawback to either?
这是明智的还是不必要的愚蠢?它有更好的方法吗?只是调用 x.toInt 并捕获异常更好,还是不那么惯用?两者是否有性能优势/缺点?
回答by Jesper
Try this:
试试这个:
def isAllDigits(x: String) = x forall Character.isDigit
foralltakes a function (in this case Character.isDigit) that takes an argument that is of the type of the elements of the collection and returns a Boolean; it returns trueif the function returns truefor all elements in the collection, and falseotherwise.
forall接受一个函数(在这种情况下Character.isDigit),它接受一个集合元素类型的参数并返回一个Boolean;true如果函数true为集合中的所有元素返回,则返回,false否则返回。
回答by Rex Kerr
Do you want to know if the string is an integer? Then .toIntit and catch the exception. Do you instead want to know if the string is all digits? Then ask one of:
您想知道字符串是否为整数吗?然后.toInt它并捕获异常。您是否想知道字符串是否都是数字?然后询问其中之一:
s.forall(_.isDigit)
s matches """\d+"""
回答by Tvaroh
You also may consider something like this:
你也可以考虑这样的事情:
import scala.util.control.Exception.allCatch
def isLongNumber(s: String): Boolean = (allCatch opt s.toLong).isDefined
// or
def isDoubleNumber(s: String): Boolean = (allCatch opt s.toDouble).isDefined
回答by Yordan Georgiev
import scala.util.Try
object NumCruncher {
def isShort(aString: String): Boolean = Try(aString.toLong).isSuccess
def isInt(aString: String): Boolean = Try(aString.toInt).isSuccess
def isLong(aString: String): Boolean = Try(aString.toLong).isSuccess
def isDouble(aString: String): Boolean = Try(aString.toDouble).isSuccess
def isFloat(aString: String): Boolean = Try(aString.toFloat).isSuccess
/**
*
* @param x the string to check
* @return true if the parameter passed is a Java primitive number
*/
def isNumber(x: String): Boolean = {
List(isShort(x), isInt(x), isLong(x), isDouble(x), isFloat(x))
.foldLeft(false)(_ || _)
}
}
回答by drexin
You could simply use a regex for this.
您可以简单地为此使用正则表达式。
val onlyDigitsRegex = "^\d+$".r
def isAllDigits(x: String) = x match {
case onlyDigitsRegex() => true
case _ => false
}
Or simply
或者干脆
def isAllDigits(x: String) = x.matches("^\d+$")
And to improve this a little bit, you can use the pimp my library pattern to make it a method on your string:
为了稍微改进这一点,您可以使用 pimp my library 模式使其成为字符串上的方法:
implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\d+$") }
"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false
回答by Xavier Guihot
Starting Scala 2.13we can use String::toDoubleOption, to determine whether a String is a decimal number or not:
开始Scala 2.13我们可以使用String::toDoubleOption, 来确定一个字符串是否是十进制数:
"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false
Similar option to determine if a String is a simple Int:
用于确定 String 是否为简单 Int 的类似选项:
"324".toIntOption.isDefined // true
"à32".toIntOption.isDefined // false
"024".toIntOption.isDefined // true
回答by akauppi
Trymight not performance-wise be the optimal choice, but otherwise it's neat:
Try可能不是性能方面的最佳选择,但除此之外它很整洁:
scala> import scala.util.Try
scala> Try{ "123x".toInt }
res4: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "123x")
scala> Try{ "123x".toInt }.isSuccess
res5: Boolean = false
回答by virtualeyes
@Jesper's answer is spot on.
@Jesper 的回答很到位。
Do NOTdo what I'm suggesting below (explanation follows)
千万不要做我以下提示(如下解释)
Since you are checking if a given string is numeric (title states you want a decimal), the assumption is that you intend to make a conversion if the forall guard passes.
由于您正在检查给定的字符串是否为数字(标题说明您想要一个小数),因此假设您打算在 forall 守卫通过时进行转换。
A simple implicit in scope will save a whopping 9 key strokes ;-)
一个简单的隐式作用域将节省多达 9 次击键 ;-)
implicit def str2Double(x: String) = x.toDouble
Why this is dangerous
为什么这是危险的
def takesDouble(x: Double) = x
The compiler will now allow takesDouble("runtime fail")since the implicit tries to convert whatever string you use to Double, with zero guarantee of success, yikes.
编译器现在将允许,takesDouble("runtime fail")因为隐式尝试将您使用的任何字符串转换为 Double,成功保证为零,哎呀。
implicit conversions then seem better suited to situations where an acceptable default value is supplied on conversion failure (which is not always the case; therefore implicit with caution)
隐式转换似乎更适合在转换失败时提供可接受的默认值的情况(情况并非总是如此;因此隐式要谨慎)
回答by Javier Ba?ez
Based on brilliant Jexter's solution, in this piece of code I take care of the NullPointerException using Option:
基于出色的 Jexter 解决方案,在这段代码中,我使用 Option 处理 NullPointerException:
def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
case Some(code) => !code.isEmpty && (code forall Character.isDigit)
case None => false
}
回答by ajmnsk
Here is one more:
这里还有一个:
import scala.util.Try
val doubleConverter: (String => Try[Double]) = (s: String) => Try{ s.map(c => if ((Character.isDigit(c) == true) || (c == '.')) Some(c) else None).flatten.mkString.toDouble }
val d1: Try[Double] = doubleConverter("+ 1234.0%")
val d2: Try[Double] = doubleConverter("+ 1234..0%")

