I am working on a function that extracts a number at the beginning of the string. Given a string it should return a case class Success
(containing the extracted number in Int
and the rest of the string) in case it found a number at the beginning and a case Object Failure
otherwise.
For that, I'm using regex pattern matching to match the number and the rest of the string into two separate variable. I then convert the number to Int
and return.
The problem: when the string provided does not contain a number at the beginning, the pattern matching fail but I don't know how to detect that it fails, and when to return my Failure.
Any ideas ?
Here is my code
sealed trait Result
case class Success(expr: String, result: Int) extends Result
case object Failure extends Result
def extractNumber(str: String) : Result = {
val pattern = "([0-9]+)(.*)".r
val pattern(count, rest) = str
if (pattern match failed) //How can I do that
return Failure
val number = count.toInt
return Success(rest, number)
}
extractNumber("100banana") match {
case Success(rest, nb) => println("sucess" + nb + ";" + rest)
case Failure => println("failure")
}
2 Answers 2
You can pattern match on the string safely and extractor the required information if pattern matches.
In the below pattern
can be used as an extractor. Read about Scala extractor pattern.
def extractNumber(str: String) : Result = {
val pattern = "([0-9]+)(.*)".r
str match {
case pattern(a, b) => Success(b, a.toInt)
case _ => Failure
}
}
Lets check if it works on Scala repl
scala> :paste
// Entering paste mode (ctrl-D to finish)
sealed trait Result
case class Success(expr: String, result: Int) extends Result
case object Failure extends Result
def extractNumber(str: String) : Result = {
val pattern = "([0-9]+)(.*)".r
str match {
case pattern(a, b) => Success(b, a.toInt)
case _ => Failure
}
}
// Exiting paste mode, now interpreting.
defined trait Result
defined class Success
defined object Failure
extractNumber: (str: String)Result
scala> extractNumber("123192731qwlejqwlkje")
res0: Result = Success(qwlejqwlkje,123192731)
Looks like it works
Lets check what happens in case of failure.
scala> extractNumber("qwlejqwlkje")
res1: Result = Failure
Comments
Instead of using deconstruction:
val pattern(count, rest) = str
Try using one of the Regex API methods:
findFirstIn
returns an option -> if None, then this is "failure"findAllIn
returns aMatchIterator
that can tell info about the failure (for instance,hasNext
or whatever)
An other way is to perform just as you do, inside a try ... catch
and catch the MatchError.