- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Pattern matching on strings
Mon, 2009-03-16, 19:36
Hello,
I want to do something like:
str match {
case "prefix1" :: suffix => ...
case "prefix2" :: suffix => ...
case prefix :: "suffix" => ...
}
Is this kind of matching possible with Scala?
I know that behind-the-scenes there is recursive structure (List) involved and not flat one but still I wonder if this
can be handled nicely in Scala somehow.
Mon, 2009-03-16, 20:07
#2
Re: Pattern matching on strings
Normen Müller pisze:
> Grzegorz Kossakowski wrote:
>> str match {
>> case "prefix1" :: suffix => ...
>
> As strings a sequences try:
>
> case Seq('p','r','e','f','i','x','1',suffix@_*) => ...
Yes, this will work but it's far from being easy to use.
Is there any syntax sugar for it?
Mon, 2009-03-16, 20:17
#3
Re: Pattern matching on strings
On Mon, Mar 16, 2009 at 07:36:17PM +0100, Grzegorz Kossakowski wrote:
> str match {
> case "prefix1" :: suffix => ...
> case "prefix2" :: suffix => ...
> case prefix :: "suffix" => ...
> }
>
> Is this kind of matching possible with Scala?
Not quite like that. I can think of a bunch of not entirely satisfying
approaches. Here's a nice unappealing one:
scala> "abcdefgh".toSeq match { case Seq('a', 'b', 'c', x @ _*) => x.mkString }
res1: String = defgh
You can always do this sort of thing:
str match {
case x if x startsWith "prefix1" => ...
case x if x endsWith "suffix" => ...
}
Here's the best I could do with extractors on short notice, maybe
someone can be cleverer, perhaps using implicits.
object o {
case class Pre(prefix: String) {
def unapply(x: String) = if (x startsWith prefix) Some(x.substring(prefix.length)) else None
}
case class Suff(suffix: String) {
def unapply(x: String) = if (x endsWith suffix) Some(x.substring(0, x.length - suffix.length)) else None
}
def go(s: String) = {
val p1 = Pre("abcd")
val s1 = Suff("efgh")
s match {
case p1(x) => "'" + x + "' left"
case s1(x) => "'" + x + "' left"
case x => "no match"
}
}
}
scala> o.go("abcdbling")
res0: java.lang.String = 'bling' left
scala> o.go("blongefgh")
res1: java.lang.String = 'blong' left
In real life I just use regexps.
Mon, 2009-03-16, 20:27
#4
Re: Pattern matching on strings
On Monday March 16 2009, Grzegorz Kossakowski wrote:
> Normen Müller pisze:
> > Grzegorz Kossakowski wrote:
> >> str match {
> >> case "prefix1" :: suffix => ...
> >
> > As strings a sequences try:
> >
> > case Seq('p','r','e','f','i','x','1',suffix@_*) => ...
>
> Yes, this will work but it's far from being easy to use.
>
> Is there any syntax sugar for it?
Introduce an implicit conversion for String to Seq into the context
where you want to write those cases?
Randall Schulz
Mon, 2009-03-16, 20:37
#5
Re: Pattern matching on strings
2009/3/16 Grzegorz Kossakowski :
> Hello,
>
> I want to do something like:
>
> str match {
> case "prefix1" :: suffix => ...
> case "prefix2" :: suffix => ...
> case prefix :: "suffix" => ...
> }
>
> Is this kind of matching possible with Scala?
>
> I know that behind-the-scenes there is recursive structure (List) involved and not flat one but still I wonder if this
> can be handled nicely in Scala somehow.
>
I'd use a regex:
scala> val re1 = "abc(.*)".r
re1: scala.util.matching.Regex = abc(.*)
scala> "abcxyz" match {
| case re1(x) => println(x)
| case _ => println("not found")
| }
xyz
Cheers
Mon, 2009-03-16, 20:47
#6
Re: Pattern matching on strings
martin odersky pisze:
> I'd use a regex:
>
> scala> val re1 = "abc(.*)".r
> re1: scala.util.matching.Regex = abc(.*)
>
> scala> "abcxyz" match {
> | case re1(x) => println(x)
> | case _ => println("not found")
> | }
> xyz
If I want to check what kind of suffix I've got I should use guard in case statement, right?
Mon, 2009-03-16, 20:57
#7
Re: Pattern matching on strings
On Mon, Mar 16, 2009 at 08:21:48PM +0100, martin odersky wrote:
> scala> val re1 = "abc(.*)".r
> re1: scala.util.matching.Regex = abc(.*)
>
> scala> "abcxyz" match {
> | case re1(x) => println(x)
> | case _ => println("not found")
> | }
> xyz
Isn't this (along with other similar examples) a compelling reason to
allow some way for an expression to stand for a StableId without
having to bind it to a temporary name somewhere far away?
Lauri
Tue, 2009-03-17, 15:57
#8
Re: Pattern matching on strings
Grzegorz Kossakowski wrote:
> If I want to check what kind of suffix I've got I should use guard in case statement, right?
>
Actually, since it's a match statement, you can use literals to match
groupings:
scala> val reg = "abc:(.*):(.*)".r
reg: scala.util.matching.Regex = abc:(.*):(.*)
scala> "abc:xyz:123" match {
| case reg("def", x) => print("DEF!")
| case reg("xyz", y) => print("xyz=>" + y)
| case reg(x, y) => print(x + ":" + y)
| }
xyz=>123
scala>
Tue, 2009-03-17, 20:27
#9
Re: Pattern matching on strings
Derek Chen-Becker pisze:
> Grzegorz Kossakowski wrote:
>> If I want to check what kind of suffix I've got I should use guard in case statement, right?
>>
>
> Actually, since it's a match statement, you can use literals to match
> groupings:
>
> scala> val reg = "abc:(.*):(.*)".r
> reg: scala.util.matching.Regex = abc:(.*):(.*)
>
> scala> "abc:xyz:123" match {
> | case reg("def", x) => print("DEF!")
> | case reg("xyz", y) => print("xyz=>" + y)
> | case reg(x, y) => print(x + ":" + y)
> | }
> xyz=>123
>
> scala>
I didn't think about it this way. This looks sweet.
Thanks for all suggestions. I'll pick this one as it seems to closest to what I wanted to achieve.
Tue, 2009-03-17, 20:37
#10
Re: Pattern matching on strings
> Isn't this (along with other similar examples) a compelling reason to
> allow some way for an expression to stand for a StableId without
> having to bind it to a temporary name somewhere far away?
Maybe. The problem is how to distinguish between in and out parameters. I.e. in
case re1(x) =>
(x) is a bound variable, not an in-parameter. There are of course ways
to specify a disambiguation, for instance, you could say that in
case f(args1)...(argsN) =>
all but the last argument list are in-parameters whereas the last
argument list contains pattern bound variables. It's possible to do
this, but the question is whether it's worth the complications, and
whether it's clear enough for readers.
Cheers
Tue, 2009-03-17, 21:27
#11
Re: Pattern matching on strings
On Tue, Mar 17, 2009 at 08:23:57PM +0100, martin odersky wrote:
> > Isn't this (along with other similar examples) a compelling reason to
> > allow some way for an expression to stand for a StableId without
> > having to bind it to a temporary name somewhere far away?
>
> Maybe. The problem is how to distinguish between in and out parameters.
In https://lampsvn.epfl.ch/trac/scala/ticket/785 I suggested that an
expression-as-StableId in a pattern could be indicated by wrapping the
expression in brackets. Hence, your example would be written as:
"abcxyz" match {
case {"abc(.*)".r}(x) => println(x)
case _ => println("not found")
}
To me this syntax extension wouldn't seem to be too intrusive.
Lauri
Sun, 2009-03-22, 21:47
#12
Re: Pattern matching on strings
On Tue, Mar 17, 2009 at 8:47 PM, Lauri Alanko wrote:
> On Tue, Mar 17, 2009 at 08:23:57PM +0100, martin odersky wrote:
>> > Isn't this (along with other similar examples) a compelling reason to
>> > allow some way for an expression to stand for a StableId without
>> > having to bind it to a temporary name somewhere far away?
>>
>> Maybe. The problem is how to distinguish between in and out parameters.
>
> In https://lampsvn.epfl.ch/trac/scala/ticket/785 I suggested that an
> expression-as-StableId in a pattern could be indicated by wrapping the
> expression in brackets. Hence, your example would be written as:
>
> "abcxyz" match {
> case {"abc(.*)".r}(x) => println(x)
> case _ => println("not found")
> }
>
Yes, maybe. I fear for other readers it would look strange. I am not
sufficiently convinced yet it's a win, and also want to stop adding to
the syntax of Scala for a while.
Cheers
Grzegorz Kossakowski wrote:
> str match {
> case "prefix1" :: suffix => ...
As strings a sequences try:
case Seq('p','r','e','f','i','x','1',suffix@_*) => ...
> case "prefix2" :: suffix => ...
> case prefix :: "suffix" => ...
> }
>
> Is this kind of matching possible with Scala?
>
> I know that behind-the-scenes there is recursive structure (List) involved and not flat one but still I wonder if this
> can be handled nicely in Scala somehow.
>
Cheers,