Scala: split a string using pattern matching

Is it possible to split the string into tokens somehow like

" user@domain.com " match { case name :: "@" :: domain :: "." :: zone => doSmth(name, domain, zone) } 

In other words, just like lists ...

+7
source share
3 answers

Yes, you can do it with Scala Regex .

I found a regex on this site , feel free to use another if this doesn't suit you:

 [-0-9a-zA-Z.+_] +@ [-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,4} 

The first thing we need to do is add parentheses around the groups:

 ([-0-9a-zA-Z.+_]+)@([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4}) 

With this, we have three groups: the part before @ , between @ and . and finally TLD.

Now we can create a Scala regex from it, and then use Scala to match the unapply pattern to get groups from Regex bound to variables:

 val Email = """([-0-9a-zA-Z.+_]+)@([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4})""".r Email: scala.util.matching.Regex = ([-0-9a-zA-Z.+_]+)@([-0-9a-zA-Z.+_]+)\.([a-zA-Z] {2,4}) " user@domain.com " match { case Email(name, domain, zone) => println(name) println(domain) println(zone) } // user // domain // com 
+19
source

In general, regex is terribly inefficient, therefore not recommended.

You can do this by using Scala pattern matching by calling .toList on your line to include it in the [Char] list. Then your parts name , domain and zone will also be List [Char], to return them to Strings, use .mkString. Although I'm not sure how effective this is.

I tested basic string operations (e.g., substring, indexOf, etc.) for various use cases vs regex, and the regex is usually an order or two slower. And, of course, the regular expression is terribly unreadable.

UPDATE: it is best to use Parsers, either your own Scala or Parboiled2

+3
source

Starting with Scala 2.13 , you can map String to a pattern by canceling string interpolation :

 val s" $user@ $domain.$zone" = " user@domain.com " // user: String = "user" // domain: String = "domain" // zone: String = "com" 

If you expect incorrect data, you can also use the comparison operator:

 " user@domain.com " match { case s" $user@ $domain.$zone" => Some(user, domain, zone) case _ => None } // Option[(String, String, String)] = Some(("user", "domain", "com")) 
0
source

All Articles