/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ package scala.collection package immutable import generic._ import mutable.Builder import scala.util.matching.Regex import scala.math.ScalaNumber /** * @since 2.8 */ object StringLike { // just statics for companion class. private final val LF: Char = 0x0A private final val FF: Char = 0x0C private final val CR: Char = 0x0D private final val SU: Char = 0x1A } import StringLike._ /** * @since 2.8 */ trait StringLike[+Repr] extends IndexedSeqOptimized[Char, Repr] with Ordered[String] { self => /** Creates a string builder buffer as builder for this class */ protected[this] def newBuilder: Builder[Char, Repr] /** Return element at index `n` * @throws IndexOutofBoundsException if the index is not valid */ def apply(n: Int): Char = toString charAt n def length: Int = toString.length override def mkString = toString /** Return the current string concatenated `n` times. */ def * (n: Int): String = { val buf = new StringBuilder for (i <- 0 until n) buf append toString buf.toString } override def compare(other: String) = toString compareTo other private def isLineBreak(c: Char) = c == LF || c == FF /** * Strip trailing line end character from this string if it has one. * * A line end character is one of *
.stripLineEnd
to all lines
* returned by linesWithSeparators
.
*/
def lines: Iterator[String] =
linesWithSeparators map (line => new WrappedString(line).stripLineEnd)
/** Return all lines in this string in an iterator, excluding trailing line
* end characters, i.e. apply .stripLineEnd
to all lines
* returned by linesWithSeparators
.
*/
def linesIterator: Iterator[String] =
linesWithSeparators map (line => new WrappedString(line).stripLineEnd)
/** Returns this string with first character converted to upper case */
def capitalize: String =
if (toString == null) null
else if (toString.length == 0) ""
else {
val chars = toString.toCharArray
chars(0) = chars(0).toUpper
new String(chars)
}
/** Returns this string with the given prefix
stripped. */
def stripPrefix(prefix: String) =
if (toString.startsWith(prefix)) toString.substring(prefix.length)
else toString
/** Returns this string with the given suffix
stripped. */
def stripSuffix(suffix: String) =
if (toString.endsWith(suffix)) toString.substring(0, toString.length() - suffix.length)
else toString
/**
* For every line in this string:
*
*
* Strip a leading prefix consisting of blanks or control characters
* followed by marginChar
from the line.
*
*/
def stripMargin(marginChar: Char): String = {
val buf = new StringBuilder
for (line <- linesWithSeparators) {
val len = line.length
var index = 0
while (index < len && line.charAt(index) <= ' ') index += 1
buf append
(if (index < len && line.charAt(index) == marginChar) line.substring(index + 1) else line)
}
buf.toString
}
/**
* For every line in this string:
*
*
* Strip a leading prefix consisting of blanks or control characters
* followed by |
from the line.
*
*/
def stripMargin: String = stripMargin('|')
private def escape(ch: Char): String = "\\Q" + ch + "\\E"
@throws(classOf[java.util.regex.PatternSyntaxException])
def split(separator: Char): Array[String] = toString.split(escape(separator))
@throws(classOf[java.util.regex.PatternSyntaxException])
def split(separators: Array[Char]): Array[String] = {
val re = separators.foldLeft("[")(_+escape(_)) + "]"
toString.split(re)
}
/** You can follow a string with `.r', turning
* it into a Regex. E.g.
*
* """A\w*""".r is the regular expression for identifiers starting with `A'.
*/
def r: Regex = new Regex(toString)
def toBoolean: Boolean = parseBoolean(toString)
def toByte: Byte = java.lang.Byte.parseByte(toString)
def toShort: Short = java.lang.Short.parseShort(toString)
def toInt: Int = java.lang.Integer.parseInt(toString)
def toLong: Long = java.lang.Long.parseLong(toString)
def toFloat: Float = java.lang.Float.parseFloat(toString)
def toDouble: Double = java.lang.Double.parseDouble(toString)
private def parseBoolean(s: String): Boolean =
if (s != null) s.toLowerCase match {
case "true" => true
case "false" => false
case _ => throw new NumberFormatException("For input string: \""+s+"\"")
}
else
throw new NumberFormatException("For input string: \"null\"")
/* !!! causes crash?
def toArray: Array[Char] = {
val result = new Array[Char](length)
toString.getChars(0, length, result, 0)
result
}
*/
private def unwrapArg(arg: Any): AnyRef = arg match {
case x: ScalaNumber => x.underlying
case x => x.asInstanceOf[AnyRef]
}
/**
* Uses the underlying string as a pattern (in a fashion similar to
* printf in C), and uses the supplied arguments to fill in the
* holes.
*
* The interpretation of the formatting patterns is described in
*
* java.util.Formatter
, with the addition that
* classes deriving from `ScalaNumber` (such as `scala.BigInt` and
* `scala.BigDecimal`) are unwrapped to pass a type which `Formatter`
* understands.
*
*
* @param args the arguments used to instantiating the pattern.
* @throws java.lang.IllegalArgumentException
*/
def format(args : Any*): String =
java.lang.String.format(toString, args map unwrapArg: _*)
/**
* Like `format(args*)` but takes an initial `Locale` parameter
* which influences formatting as in `java.lang.String`'s format.
*
*
* The interpretation of the formatting patterns is described in
*
* java.util.Formatter
, with the addition that
* classes deriving from `ScalaNumber` (such as `scala.BigInt` and
* `scala.BigDecimal`) are unwrapped to pass a type which `Formatter`
* understands.
*
*
* @param locale an instance of `java.util.Locale`
* @param args the arguments used to instantiating the pattern.
* @throws java.lang.IllegalArgumentException
*/
def formatLocal(l: java.util.Locale, args: Any*): String =
java.lang.String.format(l, toString, args map unwrapArg: _*)
}