Showing posts with label raw strings. Show all posts
Showing posts with label raw strings. Show all posts
Thursday, October 1, 2009
Strings
This topic simply shows several things that can be done with strings. It is not exhaustive and focusses of things that cannot as easily be done with java strings.
Note: Because I am using Scala 2.7 we often need to use mkString to convert the processed string from a sequence of characters to a string. In scala 2.8 this is not required.
Note: Because I am using Scala 2.7 we often need to use mkString to convert the processed string from a sequence of characters to a string. In scala 2.8 this is not required.
- /*
- Making use of raw strings to create a multi line string
- I add a | at the beginning of each line so that we can line up the quote nicely
- in source code then later strip it from the string using stripMargin
- */
- scala> val quote = """|I don-t consider myself a pessimist.
- | |I think of a pessimist as someone who is waiting for it to rain.
- | |And I feel soaked to the skin.
- |
- | |Leonard Cohen"""
- quote: java.lang.String =
- |I don-t consider myself a pessimist.
- |I think of a pessimist as someone who is waiting for it to rain.
- |And I feel soaked to the skin.
-
- |Leonard Cohen
- // capilize the first character of each line
- scala> val capitalized = quote.lines.
- | map( _.trim.capitalize).mkString("\n")
- capitalized: String =
- |I don-t consider myself a pessimist.
- |I think of a pessimist as someone who is waiting for it to rain.
- |And I feel soaked to the skin.
- |Leonard Cohen
- // remove the margin of each line
- scala> quote.stripMargin
- res1: String =
- I don-t consider myself a pessimist.
- I think of a pessimist as someone who is waiting for it to rain.
- And I feel soaked to the skin.
-
- Leonard Cohen
- // this is silly. I reverse the order of each word but keep the words in order
- scala> quote.stripMargin.
- | lines.
- | map( _.split(" ").
- | map(_.reverse).
- | mkString (" ")).
- | mkString("\n")
- res16: String =
- I t-nod redisnoc flesym a .tsimissep
- I kniht fo a tsimissep sa enoemos ohw si gnitiaw rof ti ot .niar
- dnA I leef dekaos ot eht .niks
- dranoeL nehoC
- scala> val myPatch = "-->This is my patch<--"
- myPatch: java.lang.String = -->This is my patch<--
- // I replace the characters from point 10 in the string to myPatch.length
- // (the full patch string)
- scala> quote.patch(10, myPatch, myPatch.length).mkString
- res21: String =
- |I don-t c-->This is my patch<--mist.
- |I think of a pessimist as someone who is waiting for it to rain.
- |And I feel soaked to the skin.
-
- |Leonard Cohen
- // drop the first 3 lines of the string.
- // there is also a take method
- scala> quote.lines.drop(3).mkString("\n").stripMargin
- res25: String =
-
- Leonard Cohen
- // a bunch of examples of converting strings
- scala> "1024".toInt
- res26: Int = 1024
- scala> "1024".toFloat
- res27: Float = 1024.0
- scala> "1024".toDouble
- res28: Double = 1024.0
- scala> "1024".toLong
- res29: Long = 1024
- scala> "102".toByte
- res31: Byte = 102
- scala> "true".toBoolean
- res32: Boolean = true
- // format uses the java.util.Formatter class to format a string
- scala> "Hello %s,\nThe date is %2$tm %2$te,%2$tY".format("Jesse", new java.util.Date())
- res35: String =
- Hello Jesse,
- The date is 09 30,2009
- /*
- More silliness
- I am replacing every other character with the character of the reversed string
-
- this is done by
- 1. convert string to a list and zip it together with its reverse
- We may still need to cover zipping. It basically matches up the
- corresponding elements of two lists into one list
- so 1,2,3 and one,two,three zipped would be (1,one),(2,two),(3,three)
- 2. Add an index to each element in the list with zipWithIndex
- 3. Use map to check if the element is an odd element using the index and return either the original element or the reversed element
-
- Not useful but interesting use of functional idioms
- */
- scala> quote.toList.
- | zip(quote.reverse.toList).
- | zipWithIndex.
- | map {
- | case ((original,reversed),index) if(index % 2 == 0) => original
- | case ((original,reversed),index) => reversed
- | }.
- | mkString
- res42: String = |e oo -r noes|d r m s l e s m s . . i s e t o e|a shlne f anp|s i i t a o e n h .siwrioi gifrrfig ioirwis. h n e o a t i i s|pna f enlhs a|e o t e s i . . s m s e l s m r d|seon r- oo e|
- // filter out all non-vowels
- scala> quote.filter( "aeiou" contains _ ).mkString
- res51: String = ooieeaeiiioaeiiaoeoeoiaiioioaieeoaeoeieoaoe
Labels:
beginner,
raw strings,
Scala,
String
Wednesday, September 16, 2009
Matching Regular expressions
This topic is derived from the blog post: Using pattern matching with regular expressions in Scala
The Regex class in Scala provides a very handy feature that allows you to match against regular expressions. This makes dealing with certain types of regular expression very clean and easy to follow.
What needs to be done is to create a Regex class and assign it to a val. It is recommended that the val starts with an Uppercase letter, see the topic of matching about the assumptions matching makes based on the first letter of the Match case clause.
There is nothing like examples to help explain an idea:
The Regex class in Scala provides a very handy feature that allows you to match against regular expressions. This makes dealing with certain types of regular expression very clean and easy to follow.
What needs to be done is to create a Regex class and assign it to a val. It is recommended that the val starts with an Uppercase letter, see the topic of matching about the assumptions matching makes based on the first letter of the Match case clause.
There is nothing like examples to help explain an idea:
- // I normally use raw strings (""") for regular expressions so that I don't have to escape all \ characters
- // There are two ways to create Regex objects.
- // 1. Use the RichString's r method
- // 2. Create it using the normal Regex constructor
- scala> val Name = """(\w+)\s+(\w+)""".r
- Name: scala.util.matching.Regex = (\w+)\s+(\w+)
- scala> import scala.util.matching._
- import scala.util.matching._
- // Notice the val name starts with an upper case letter
- scala> val Name = new Regex("""(\w+)\s+(\w+)""")
- Name: scala.util.matching.Regex = (\w+)\s+(\w+)
- scala> "Jesse Eichar" match {
- | case Name(first,last) => println("found: ", first, last)
- | case _ => println("oh no!")
- | }
- (found: ,Jesse,Eichar)
- scala> val FullName = """(\w+)\s+(\w+)\s+(\w+)""".r
- FullName: scala.util.matching.Regex = (\w+)\s+(\w+)\s+(\w+)
- // If you KNOW that the match will work you can assign it to a variable
- // Only do this if you are sure the match will work otherwise you will get a MatchError
- scala> val FullName(first, middle, last) = "Jesse Dale Eichar"
- first: String = Jesse
- middle: String = Dale
- last: String = Eichar
Labels:
intermediate,
match,
MatchError,
matching,
raw strings,
regex,
regular expression,
Scala
Thursday, September 3, 2009
Adding methods using Traits
One useful application of a trait is the case where you want to add functionality to an existing class. In this example I have a class provided by a third party library (in this just a simple StringReader class from the Java library). But I want to be able to read lines as well as use the standard read methods.
One solution is to create a trait and when I instantiate the StringReader mix in the new trait. Code like
The other solution that can be used is to create an implicit conversion from StringReader to some other class. There are two draw backs here:
Here is a simple example:
One solution is to create a trait and when I instantiate the StringReader mix in the new trait. Code like
new StringReader() with Lines
results in a new class that extends StringReader and the trait Lines. As a result we have all the methods of StringReader and Lines. The biggest benefit is that we can define the trait to work with any Reader and then when we create the real instance we can mix it in to any class that extends Reader.The other solution that can be used is to create an implicit conversion from StringReader to some other class. There are two draw backs here:
- It is harder to tell what is happening
- A trait can contain state but a "view" (which is what you get when one class is implicitly converted to another class) has no state it is just a view of the original class. In this example a view would work but in other examples like creating a pushback reader, it would not work.
Here is a simple example:
- scala> trait Lines {
- | // the self type declares what type of class the trait can be applied to
- | // if there is no self type then it is assumed it can be applied to Any type
- | self:java.io.Reader =>
- | def nextLine:Option[String] = {
- | val builder = new scala.collection.mutable.StringBuilder()
- |
- | var next = read()
- |
- | while( next != -1 && next.toByte.toChar != '\n' ){
- | builder += next.toByte.toChar
- | next = read()
- | }
- |
- | if( builder.isEmpty ) None
- | else Some(builder.toString)
- | }
- | }
- defined trait Lines
- // Strings starting and ending with (""") are called raw strings. All characters
- // within """ """ are automatically escaped.
- // I am creating a reader and mixing in the Lines trait on construction
- scala> val reader = new java.io.StringReader( """line one
- | line two""" with Lines
- reader: java.io.StringReader with Lines = $anon1ドル@3850620f
- scala> reader.nextLine
- res0: Option[String] = Some(line one)
- scala> reader.nextLine
- res1: Option[String] = Some(line two)
- scala> reader.nextLine
- res2: Option[String] = None
- scala> reader.nextLine
- res3: Option[String] = None
- // we can define a method that takes a reader with lines
- scala> def toCollection( reader:java.io.StringReader with Lines) = {
- | def collect:List[String] = reader.nextLine match {
- | case None => Nil
- | // we do not need to worry about stack overflow
- | // because of tail recursion. This method cannot be
- | // extended and collect is the last like in the collect
- | // method so this method will be transformed into a loop
- | case Some( line ) => line :: collect
- | }
- |
- | collect
- | }
- toCollection: (reader: java.io.StringReader with Lines)List[String]
- scala> toCollection( new java.io.StringReader( "line one\nlinetwo" ) with Lines).size
- res8: Int = 2
Labels:
raw strings,
Scala,
self-type,
tail-recursion,
traits,
with
Subscribe to:
Comments (Atom)