How to check whether a String fully matches a Regex

825 views
Skip to first unread message

Roberto Tyley

unread,
Jan 10, 2013, 6:38:26 PM1/10/13
to scala-i...@googlegroups.com

I'd like to filter a list of strings based on complete regex match, ie only retain strings that fully match the regex. What's the canonical way to do this in Scala?

This is one long-winded way of getting the result I'd like (only returning "foo", not "foot"):

scala> val regex = "f*o".r
scala> List("foo","bar","foot").filter(regex.pattern.matcher(_).matches)
res24: List[String] = List(foo)

The filter expression seems long, but everything else (for instance involving unapplySeq) seems longer, or in the case of using String.matches, less efficient because it means recompiling the pattern every time. The best solution seem to be to pimp the Regex class:

  implicit class RichRegex(underlying: Regex) {
    def matches(s: String) = underlying.pattern.matcher(s).matches
  }

So the code becomes:

scala> List("foo","bar","foot").filter(regex.matches)
res33: List[String] = List(foo)

I'm inclined to submit a pull-request to add this method to the Regex class, unless there is a better way to do this that I haven't thought of?

One alternative is to just add anchors (ie "^f.o$") to the regex expression, but this isn't too attractive to me - perhaps just because I'm used to the semantics of the Java Matcher.matches() method.


Som Snytt

unread,
Jan 10, 2013, 7:21:14 PM1/10/13
to scala-i...@googlegroups.com
On Thu, Jan 10, 2013 at 3:38 PM, Roberto Tyley <robert...@gmail.com> wrote:

I'd like to filter a list of strings based on complete regex match, ie only retain strings that fully match the regex.

scala> val regex = "f.*o".r
regex: scala.util.matching.Regex = f.*o


scala> List("foo","bar","foot")
res0: List[String] = List(foo, bar, foot)

scala> .filter { case regex() => true case _ => false }
res1: List[String] = List(foo)
 
The scaladoc says there is no method returning a boolean.  I think there must be a reason, and also a reason people keep proposing to add one.

Som Snytt

unread,
Jan 10, 2013, 7:28:37 PM1/10/13
to scala-i...@googlegroups.com
Sorry about that, I didn't notice which ML you were addressing.

But I guess my comment is still germane.

Roberto Tyley

unread,
Jan 10, 2013, 7:47:10 PM1/10/13
to scala-i...@googlegroups.com
On Friday, January 11, 2013 12:21:14 AM UTC, som-snytt wrote:
On Thu, Jan 10, 2013 at 3:38 PM, Roberto Tyley <robert...@gmail.com> wrote:
I'd like to filter a list of strings based on complete regex match, ie only retain strings that fully match the regex.
scala> .filter { case regex() => true case _ => false }

That works, though it's obviously more verbose than .filter(regex.matches)
 
The scaladoc says there is no method returning a boolean.  I think there must be a reason

That's cool, I'd just like to know what it is :-) I did search the scala-internals group for 'Regex boolean', but found nothing.



 

Daniel Sobral

unread,
Jan 10, 2013, 9:37:09 PM1/10/13
to scala-i...@googlegroups.com
The simplest solution is to use String's match method, and forsake
Regex altogether.

scala> val regex = "f.*o"
regex: String = f.*o

scala> List("foo", "bar", "foot").filter(_ matches regex)
res4: List[String] = List(foo)
--
Daniel C. Sobral

I travel to the future all the time.

Nils Kilden-Pedersen

unread,
Jan 11, 2013, 9:08:59 AM1/11/13
to scala-i...@googlegroups.com
Yes, but as stated by OP, this recompiles the regex for every element.
Reply all
Reply to author
Forward
0 new messages