Created
April 24, 2015 10:26
-
-
Save ghik/2b02927737483d4faf84 to your computer and use it in GitHub Desktop.
String interpolation + pattern matching = PROFIT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import RegexInterpolations._ | |
| val str = "My hovercraft is full of eels" | |
| str match { | |
| case r"""My (\w+)$vehicle is full of (\w+)$stuff""" => | |
| println(s"It is $stuff that my $vehicle is full of.") | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.regex.Pattern | |
| object RegexInterpolations { | |
| implicit class Interpolations(sc: StringContext) { | |
| def r = new PartsRegex(sc.parts) | |
| } | |
| class PartsRegex(parts: Seq[String]) { | |
| private val regex = parts.mkString | |
| private val matchedGroups = { | |
| // indices of pattern's string interpolation arguments | |
| val matchedGroupIndexes = | |
| parts.iterator.map(_.length).scanLeft(0)(_ + _).map(_ - 1).drop(1).take(parts.size - 1).toSet | |
| val matchedGroupsBuilder = Seq.newBuilder[Int] | |
| var group = 0 | |
| var level = 0 | |
| var escaping = false | |
| regex.zipWithIndex.foreach { | |
| case ('(', _) if !escaping => | |
| group += 1 | |
| level += 1 | |
| case (')', index) if !escaping => | |
| level -= 1 | |
| if (matchedGroupIndexes contains index) { | |
| matchedGroupsBuilder += (group - level) | |
| } | |
| case ('\\', _) if !escaping => | |
| escaping = true | |
| case _ => | |
| escaping = false | |
| } | |
| matchedGroupsBuilder.result() | |
| } | |
| def unapplySeq(str: String) = { | |
| val matcher = Pattern.compile(regex).matcher(str) | |
| if (matcher.matches) Some(matchedGroups.map(matcher.group)) else None | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment