summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2014-08-08 21:36:27 -0700
committerSom Snytt <som.snytt@gmail.com>2014-08-08 21:36:27 -0700
commitcd2394ee43220e885bfa92f3ce34f41366bb4704 (patch)
treeabc2f880a05d3d70c0558f74dcf3933386c5a614
parent50167e3f1df664165a2ad485abace5dbce623996 (diff)
downloadscala-cd2394ee43220e885bfa92f3ce34f41366bb4704.tar.gz
scala-cd2394ee43220e885bfa92f3ce34f41366bb4704.tar.bz2
scala-cd2394ee43220e885bfa92f3ce34f41366bb4704.zip
SI-8787 If you love nulls, so does Regex
Regex is robust when unapplying null. A null never matches.
-rw-r--r--src/library/scala/util/matching/Regex.scala21
-rw-r--r--test/junit/scala/util/matching/RegexTest.scala17
2 files changed, 28 insertions, 10 deletions
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
index f35ea566ba..3d77105a1e 100644
--- a/src/library/scala/util/matching/Regex.scala
+++ b/src/library/scala/util/matching/Regex.scala
@@ -101,7 +101,7 @@ import java.util.regex.{ Pattern, Matcher }
* val copyright: Option[String] = for {
* dateP1(year, month, day) <- dateP1 findFirstIn "Last modified 2011-07-15"
* } yield year
-
+ *
* def getYears(text: String): Iterator[String] = for (dateP1(year, _, _) <- dateP1 findAllIn text) yield year
* def getFirstDay(text: String): Option[String] = for (m <- dateP2 findFirstMatchIn text) yield m group "day"
* }}}
@@ -154,7 +154,7 @@ import java.util.regex.{ Pattern, Matcher }
* interpreted as a reference to a group in the matched pattern, with numbers
* 1 through 9 corresponding to the first nine groups, and 0 standing for the
* whole match. Any other character is an error. The backslash (`\`) character
- * will be interpreted as an escape character, and can be used to escape the
+ * will be interpreted as an escape character and can be used to escape the
* dollar sign. One can use [[scala.util.matching.Regex]]'s `quoteReplacement`
* to automatically escape these characters.
*/
@@ -178,7 +178,7 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends
*
* This method attempts to match the entire input by default; to find the next
* matching subsequence, use an unanchored Regex.
-
+ *
* For example:
*
* {{{
@@ -202,10 +202,12 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends
* @param s The string to match
* @return The matches
*/
- def unapplySeq(s: CharSequence): Option[List[String]] = {
- val m = pattern matcher s
- if (runMatcher(m)) Some((1 to m.groupCount).toList map m.group)
- else None
+ def unapplySeq(s: CharSequence): Option[List[String]] = s match {
+ case null => None
+ case _ =>
+ val m = pattern matcher s
+ if (runMatcher(m)) Some((1 to m.groupCount).toList map m.group)
+ else None
}
/** Tries to match the String representation of a [[scala.Char]].
@@ -253,7 +255,7 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends
* and the result of that match is used.
*/
def unapplySeq(m: Match): Option[List[String]] =
- if (m.matched == null) None
+ if (m == null || m.matched == null) None
else if (m.matcher.pattern == this.pattern) Some((1 to m.groupCount).toList map m.group)
else unapplySeq(m.matched)
@@ -297,7 +299,6 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends
*/
def findAllIn(source: CharSequence) = new Regex.MatchIterator(source, this, groupNames)
-
/** Return all non-overlapping matches of this regexp in given character sequence as a
* [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]].
*
@@ -588,7 +589,7 @@ object Regex {
}
- /** Provides information about a succesful match.
+ /** Provides information about a successful match.
*/
class Match(val source: CharSequence,
private[matching] val matcher: Matcher,
diff --git a/test/junit/scala/util/matching/RegexTest.scala b/test/junit/scala/util/matching/RegexTest.scala
index d25842cc57..5b13397d6a 100644
--- a/test/junit/scala/util/matching/RegexTest.scala
+++ b/test/junit/scala/util/matching/RegexTest.scala
@@ -27,4 +27,21 @@ class RegexTest {
assertEquals("1", x)
assertEquals("1", y)
}
+
+ @Test def t8787nullMatch() = {
+ val r = """\d+""".r
+ val s: String = null
+ val x = s match { case r() => 1 ; case _ => 2 }
+ assertEquals(2, x)
+ }
+
+ @Test def t8787nullMatcher() = {
+ val r = """(\d+):(\d+)""".r
+ val s = "1:2 3:4 5:6"
+ val z = ((r findAllMatchIn s).toList :+ null) flatMap {
+ case r(x, y) => Some((x.toInt, y.toInt))
+ case _ => None
+ }
+ assertEquals(List((1,2),(3,4),(5,6)), z)
+ }
}