{"id":646,"date":"2011-10-05T21:47:00","date_gmt":"2011-10-05T21:47:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/scala-tutorial-regular-expressions-matching-and-substitutions-with-the-scala-util-matching-api.html"},"modified":"2012-10-21T20:32:10","modified_gmt":"2012-10-21T20:32:10","slug":"scala-tutorial-regular-expressions_05","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html","title":{"rendered":"Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">\n<h2>         Preface<\/h2>\n<p>This is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on <a href=\"http:\/\/icl-f11.utcompling.com\/links\">the links page of the Computational Linguistics course<\/a> I\u2019m creating these for.&nbsp;Additionally you can find this and other tutorial series on the JCG <a href=\"http:\/\/www.javacodegeeks.com\/p\/java-tutorials.html\">Java Tutorials<\/a> page.<\/p>\n<p>This post is the second of two about regular expressions (regexes), which are essential for a wide range of programming tasks, and for computational linguistics tasks in particular. If you haven\u2019t read it already, you might want to start with <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions.html\">the first post about regexes<\/a>. For what its worth, this post might actually be of some use to programmers who already are reasonably familiar with Scala but who haven\u2019t used regular expressions much yet: it might saving some poking around to figure out how to do things you already know how to do quite well in other languages.<\/p>\n<p>The use of regular expressions for capturing values for variable assignment and cases in match expressions is a very clean, well-thought out and highly useful trait of support for regular expressions in the Scala language. However, their use for more complex string matching and substitution is, frankly, much less straightforward than it is in languages with built-in support for regular expressions, such as Perl (which\u2014speaking as one who has coded a lot in Perl\u2014you do *not* want to use for general programming). Scala is fully capabable in that you can use regular expressions fully, but you\u2019ll need to use it via the Regex API. In other words, you need to use a number of commands, not all of which as as straightforward as they could be. (This is not a rant, though I do obviously wish regular expressions were supported more naturally in Scala.)<\/p>\n<p>Though I\u2019ll refer to what I\u2019m doing below as using the Regex API, I\u2019ll note first that this makes it sound like a bigger deal than it is. It just means you are directly using classes and objects from <a href=\"http:\/\/www.scala-lang.org\/api\/current\/scala\/util\/matching\/package.html\">the <strong>scala.util.matching<\/strong> package<\/a> rather than using some of the special syntax and integration with Scala pattern matching we saw in the previous post.<\/p>\n<h2>         More extensive matching<\/h2>\n<p>First off, let\u2019s do what we did with pattern matching in the previous post, but now using the <strong>Regex<\/strong> class and the methods available to it to achieve the same ends. We can then start working with finding multiple matches and performing substitutions.<\/p>\n<p>To recap, recall the name regular expression and how we can use it to initialize a group of variables based on matching a given string.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val Name = \"\"\"(Mr|Mrs|Ms)\\. ([A-Z][a-z]+) ([A-Z][a-z]+)\"\"\".r\r\nName: scala.util.matching.Regex = (Mr|Mrs|Ms)\\. ([A-Z][a-z]+) ([A-Z][a-z]+)\r\n \r\nscala&gt; val smith = \"Mr. John Smith\"\r\nsmith: java.lang.String = Mr. John Smith\r\n \r\nscala&gt; val Name(title, first, last) = smith\r\ntitle: String = Mr\r\nfirst: String = John\r\nlast: String = Smith\r\n<\/pre>\n<p>Instead of doing it this way, let\u2019s instead use the API methods. We start by using the regex to find the matches, if any. The method <strong>findAllIn<\/strong> of Regex does this for us.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchesFound = Name.findAllIn(smith)\r\nmatchesFound: scala.util.matching.Regex.MatchIterator = non-empty iterator\r\n<\/pre>\n<p>The result is an <em>iterator<\/em>, which is an object that is like a list in that you can iterate over its elements with <strong>for<\/strong> expressions and <strong>foreach<\/strong>, use <strong>map<\/strong> to transform its values, and more.<\/p>\n<pre class=\"brush: scala;\">scala&gt; matchesFound.foreach(println)\r\nMr. John Smith\r\n<\/pre>\n<p>However, unlike Lists, you can only do this a single time. As the following shows, after you iterate through it once, its elements are used up.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchesFound = Name.findAllIn(smith)\r\nmatchesFound: scala.util.matching.Regex.MatchIterator = non-empty iterator\r\n \r\nscala&gt; matchesFound.foreach(println)\r\nMr. John Smith\r\n \r\nscala&gt; matchesFound.foreach(println)\r\n<\/pre>\n<p>Another difference is that you cannot index into its elements directly.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchesFound = Name.findAllIn(smith)\r\nmatchesFound: scala.util.matching.Regex.MatchIterator = non-empty iterator\r\n \r\nscala&gt; matchesFound(0)\r\n&lt;console&gt;:11: error: scala.util.matching.Regex.MatchIterator does not take parameters\r\nmatchesFound(0)\r\n^\r\n<\/pre>\n<p>If you wish to do that, you need to just call <strong>toList<\/strong> on the <strong>MatchIterator<\/strong>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchList = Name.findAllIn(smith).toList\r\nmatchList: List[String] = List(Mr. John Smith)\r\n \r\nscala&gt; matchList.foreach(println)\r\nMr. John Smith\r\n \r\nscala&gt; matchList.foreach(println)\r\nMr. John Smith\r\n<\/pre>\n<p>I\u2019ll primarily work with the match results as a List for the remainder of this tutorial. However, note that when you are programming, you should consider whether you really need to do this\u2014usually, the iterator will be sufficient and it has the advantage of being a more efficient.<\/p>\n<p>Note above that what we have is a <strong>List[String]<\/strong>. That means we can see which portions of a string matched, which could include multiple matches.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val sentence = \"Mr. John Smith said hello to Ms. Jane Hill and then to Mr. Bill Brown.\"\r\nsentence: java.lang.String = Mr. John Smith said hello to Ms. Jane Hill and then to Mr. Bill Brown.\r\n \r\nscala&gt; val matchList = Name.findAllIn(sentence).toList\r\nmatchList: List[String] = List(Mr. John Smith, Ms. Jane Hill, Mr. Bill Brown)\r\n<\/pre>\n<p>This will be useful in many contexts, but it won\u2019t allow us to access the match groups that were defined in the Regex. For that, we need to use the <strong>matchData<\/strong> method, which converts the MatchIterator (which offers Strings as its elements) into an <strong>Iterator[Match]<\/strong> (which offers Match objects as its elements).<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchList = Name.findAllIn(smith).matchDatamatchList: java.lang.Object with Iterator[scala.util.matching.Regex.Match] = non-empty iterator\r\n<\/pre>\n<p>Let\u2019s convert that to a List and then grab the first element.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val matchList = Name.findAllIn(smith).matchData.toList\r\nmatchList: List[scala.util.matching.Regex.Match] = List(Mr. John Smith)\r\n \r\nscala&gt; val firstMatch = matchList(0)\r\nfirstMatch: scala.util.matching.Regex.Match = Mr. John Smith\r\n<\/pre>\n<p>This Match object contains captured groups that we can access with the group method. The first index, 0, returns the entire match, and the rest access the captured groups.<\/p>\n<pre class=\"brush: scala;\">scala&gt; firstMatch.group(0)\r\nres8: String = Mr. John Smith\r\n \r\nscala&gt; val title = firstMatch.group(1)\r\ntitle: String = Mr\r\n \r\nscala&gt; val first = firstMatch.group(2)\r\nfirst: String = John\r\n \r\nscala&gt; val last = firstMatch.group(3)\r\nlast: String = Smith\r\n<\/pre>\n<p>We can get a bit closer to the original pattern matched variable assignment by packaging them up as a tuple.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val (title, first, last) = (firstMatch.group(1), firstMatch.group(2), firstMatch.group(3))\r\ntitle: String = Mr\r\nfirst: String = John\r\nlast: String = Smith\r\n<\/pre>\n<p><em>Update<\/em>: There is a more concise way to do this using the range 1 to 3 and map firstMatch.group over that range. This creates a Seq(uence), which we can pattern match on. (Thanks to @missingfaktor.)<\/p>\n<pre class=\"brush: scala;\">val Seq(title, first, last) = 1 to 3 map firstMatch.group\r\n<\/pre>\n<p>This should demonstrate why Scala\u2019s support for Regexes in patterning match is very nice for this. What you gain with the API is the ability to match multiple instances of a pattern in a string and then to perform computations with the Match results on the fly. For example, let\u2019s return to the sentence with multiple names in it and use the Name regex to say hello to every name found in it.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.findAllIn(sentence).matchData.foreach(m =&gt; println(\"Hello, \" + m.group(0)))\r\nHello, Mr. John Smith\r\nHello, Ms. Jane Hill\r\nHello, Mr. Bill Brown\r\n<\/pre>\n<p>Of course, you can choose to print only subparts of the names, such as the title and the last name.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.findAllIn(sentence).matchData.foreach(m =&gt; println(\"Hello, \" + m.group(1) + \". \" + m.group(3)))\r\nHello, Mr. Smith\r\nHello, Ms. Hill\r\nHello, Mr. Brown\r\n<\/pre>\n<p>Or you can filter the results, e.g. to only the Mr\u2019s, and then print only the first names.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.findAllIn(sentence).matchData.filter(m=&gt;m.group(1) == \"Mr\").foreach(m =&gt; println(\"Hello, \" + m.group(2)))\r\nHello, John\r\nHello, Bill\r\n<\/pre>\n<p>Notice that in the above lines, I didn\u2019t convert the MatchIterator to a List since I was happy to just go through the list once and do some actions.<\/p>\n<h2>         Performing substitutions<\/h2>\n<p>The other thing you gain is the ability to use regular expressions for substituting once class of expressions with another. For example, let\u2019s say that (for some odd reason) you would like to reverse everyone\u2019s name so that \u201c<em>Mr. John Smith<\/em>\u201d becomes \u201c<em>Mr. Smith John<\/em>\u201c. This is accomplished by using the Regex method <strong>replaceAllIn<\/strong>, which takes two arguments: the first is the original string and the second is a function that takes a Match object and returns a String.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val swapped = Name.replaceAllIn(sentence, m =&gt; m.group(1) + \". \" + m.group(3) + \" \" + m.group(2))\r\nswapped: String = Mr. Smith John said hello to Ms. Hill Jane and then to Mr. Brown Bill.\r\n<\/pre>\n<p>The variable <em>m<\/em> above is referring to each of the Match objects identified, in turn. That means we can access the groups as we did before. The thing that might feel strange at first is that the anonymous function <strong>m =&gt; m.group(1) + \u201c. \u201d + m.group(3) + \u201d \u201d + m.group(2)<\/strong> is an argument. It\u2019s not very different from the following, where we first create a named function and then pass it as an argument.<\/p>\n<pre class=\"brush: scala;\">scala&gt; def swapFirstLast = (m: scala.util.matching.Regex.Match) =&gt; m.group(1) + \". \" + m.group(3) + \" \" + m.group(2)\r\nswapFirstLast: (util.matching.Regex.Match) =&gt; java.lang.String\r\n \r\nscala&gt; val swapped = Name.replaceAllIn(sentence, swapFirstLast)swapped: String = Mr. Smith John said hello to Ms. Hill Jane and then to Mr. Brown Bill.\r\n<\/pre>\n<p>Note that now that we\u2019ve defined it, we can use that same function to map the Matches returned by <strong>findAllIn<\/strong> to their swapped versions.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val swappedNames = Name.findAllIn(sentence).matchData.map(swapFirstLast).toList\r\nswappedNames: List[java.lang.String] = List(Mr. Smith John, Ms. Hill Jane, Mr. Brown Bill)\r\n<\/pre>\n<p>The difference is that using <strong>findAllIn<\/strong> gives us the Match results themselves, whereas <strong>replaceAllIn<\/strong> replaces them in the String in situ. Whether you need to do one or the other depends on your programming needs.<\/p>\n<h2>         Determining whether an entire string matches using the Regex API<\/h2>\n<p>If you just want to know whether an entire given string matches a Regex, Scala unfortunately has a somewhat roundabout way for you to do this. First, here is the syntax, testing whether Name matches on the variables <em>smith<\/em> and <em>sentence<\/em>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.pattern.matcher(smith).matches\r\nres21: Boolean = true\r\n \r\nscala&gt; Name.pattern.matcher(sentence).matches\r\nres22: Boolean = false\r\n<\/pre>\n<p>So, <em>sentence<\/em> doesn\u2019t match (despite having three names in it) because the entire string is not a single match to Name.<\/p>\n<p>What is going on here is that we are actually using classes defined in Java for working with regular expressions. First, we get the <strong>java.util.regex.Pattern<\/strong> object associated with our <strong>scala.util.matching.Regex<\/strong> object.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.pattern\r\nres16: java.util.regex.Pattern = (Mr|Mrs|Ms)\\. ([A-Z][a-z]+) ([A-Z][a-z]+)\r\n<\/pre>\n<p>Then we use that Pattern to get a <strong>java.util.regex.Matcher<\/strong> for the string.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.pattern.matcher(smith)\r\nres17: java.util.regex.Matcher = java.util.regex.Matcher[pattern=(Mr|Mrs|Ms)\\. ([A-Z][a-z]+) ([A-Z][a-z]+) region=0,14 lastmatch=]\r\n<\/pre>\n<p>The Matcher class has a <strong>matches<\/strong> method that tells us whether there was a match or not for that string.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Name.pattern.matcher(smith).matches\r\nres18: Boolean = true\r\n<\/pre>\n<p>So, long-winded, but you can do it.<\/p>\n<p><em>Note<\/em>: there is another way to do this using Scala\u2019s standard pattern matching paradigm discussed in <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions.html\">the previous post on regexes<\/a>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; smith match { case Name(_,_,_) =&gt; true; case _ =&gt; false }\r\nres23: Boolean = true\r\n \r\nscala&gt; sentence match { case Name(_,_,_) =&gt; true; case _ =&gt; false }\r\nres24: Boolean = false\r\n<\/pre>\n<p>However, this requires the extra work of specifying the capture groups, which are being thrown away anyway.<\/p>\n<h2>         Simple substitutions with a second regular expression<\/h2>\n<p>There is another <strong>replaceAllIn<\/strong> method that takes a String defining a (fairly) standard regular expresion substitution as its second argument rather than a function from Matches to Strings. This argument defines a regular expression similar to that used in standard <em>s\/\/\/<\/em> substitutions from the Perl programming language,e.g. the following, which turns strings like \u201c<em>xyzaaaabbb123<\/em>\u201d int \u201c<em>xyzbbbaaaa123<\/em>\u201c.<\/p>\n<pre class=\"brush: bash;\">s\/(a+)(b+)\/\\2\\1\/\r\n<\/pre>\n<p>Unlike Perl (which is the same as the syntax discussed in Jurafsky and Martin\u2019s book), Scala uses <strong>$1<\/strong>, <strong>$2<\/strong>, etc. As an example, consider the first-last name swap we did before. Here it is repeated:<\/p>\n<pre class=\"brush: scala;\">scala&gt; val swapped = Name.replaceAllIn(sentence, m =&gt; m.group(1) + \". \" + m.group(3) + \" \" + m.group(2))\r\nswapped: String = Mr. Smith John said hello to Ms. Hill Jane and then to Mr. Brown Bill.\r\n<\/pre>\n<p>You can get the exact same effect somewhat more easily by constructing the replacement string with <strong>$n<\/strong> variables that refer to the groups.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val swapped2 = Name.replaceAllIn(sentence, \"$1. $3 $2\")\r\nswapped2: String = Mr. Smith John said hello to Ms. Hill Jane and then to Mr. Brown Bill.\r\n<\/pre>\n<p>This is far more concise and readable than the <strong>m.group()<\/strong> style above, so it is preferable for cases like this. However, sometimes you\u2019ll want to do some more interesting processing of the values in each group, such as changing the titles to another language and outputing only the first initial of the first name: e.g. \u201c<em>Mr. John Smith<\/em>\u201d would become \u201c<em>Sr. J. Smith<\/em>\u201d and \u201c<em>Mrs. Jane Hill<\/em>\u201d would become \u201cSra. J. Hill\u201d. It isn\u2019t clear to me how one could do this with the <strong>$n<\/strong> substitutions (if some reader is aware, please let me know). To do it with the <strong>Match =&gt; String<\/strong> function, it is straightforward. First, let\u2019s define a method that maps the titles from English to Spanish.<\/p>\n<pre class=\"brush: scala;\">def engTitle2Esp (title: String) = title match {\r\n  case \"Mr\" =&gt; \"Sr\"\r\n  case \"Mrs\" =&gt; \"Sra\"\r\n  case \"Ms\" =&gt; \"Srta\"\r\n}\r\n<\/pre>\n<p>Then we pass <strong>m.group(1)<\/strong> through that function by using <strong>engTitle2Esp(m.group(1))<\/strong>, and get just the first character of group 2 by indexing into it as <strong>m.group(2)(0)<\/strong>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val spanishized = Name.replaceAllIn(sentence, m =&gt; engTitle2Esp(m.group(1)) + \". \" + m.group(2)(0) + \". \" + m.group(3))\r\nspanishized: String = Sr. J. Smith said hello to Srta. J. Hill and then to Sr. B. Brown.\r\n<\/pre>\n<p>This gives you considerable control over how to process the replacements.<\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/bcomposes.wordpress.com\/2011\/09\/06\/first-steps-in-scala-for-beginning-programmers-part-6\/\">First steps in Scala for beginning programmers, Part 6<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Jason Baldridge at the <a href=\"http:\/\/bcomposes.wordpress.com\/\">Bcomposes<\/a> blog.<\/p>\n<p><strong><i>Related Articles :<\/i><\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-scala-repl-expressions.html\">Scala Tutorial &#8211; Scala REPL, expressions, variables, basic types, simple functions, saving and running programs, comments<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-tuples-lists-methods-on.html\">Scala Tutorial &#8211; Tuples, Lists, methods on Lists and Strings<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-conditional-execution.html\">Scala Tutorial &#8211; conditional execution with if-else blocks and matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-iteration-for.html\">Scala Tutorial &#8211; iteration, for expressions, yield, map, filter, count<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions.html\">Scala Tutorial &#8211; regular expressions, matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\">Scala Tutorial &#8211; Maps, Sets, groupBy, Options, flatten, flatMap<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html\">Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-objects-classes.html\">Scala Tutorial &#8211; objects, classes, inheritance, traits, Lists with multiple related types, apply<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scripting-compiling-main.html\">Scala Tutorial &#8211; scripting, compiling, main methods, return values of functions<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html\">Scala Tutorial &#8211; SBT, scalabha, packages, build systems<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-code-blocks-coding-style.html\">Scala Tutorial &#8211; code blocks, coding style, closures, scala documentation project<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/fun-with-function-composition-in-scala.html\">Fun with function composition in Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/how-scala-changed-way-i-think-about-my.html\">How Scala changed the way I think about my Java Code<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/testing-with-scala.html\">Testing with Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/12\/things-every-programmer-should-know.html\">Things Every Programmer Should Know<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Preface This is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on the links page of the Computational Linguistics course I\u2019m creating these for.&nbsp;Additionally you can find this and other tutorial series on the JCG Java Tutorials &hellip;<\/p>\n","protected":false},"author":67,"featured_media":227,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[235],"class_list":["post-646","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scala","tag-scala-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-10-05T21:47:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:32:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jason Baldridge\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/jasonbaldridge\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason Baldridge\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html\"},\"author\":{\"name\":\"Jason Baldridge\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\"},\"headline\":\"Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API\",\"datePublished\":\"2011-10-05T21:47:00+00:00\",\"dateModified\":\"2012-10-21T20:32:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html\"},\"wordCount\":1799,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"keywords\":[\"Scala Tutorial\"],\"articleSection\":[\"Scala\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html\",\"name\":\"Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"datePublished\":\"2011-10-05T21:47:00+00:00\",\"dateModified\":\"2012-10-21T20:32:10+00:00\",\"description\":\"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-regular-expressions_05.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JVM Languages\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Scala\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\\\/scala\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\",\"name\":\"Jason Baldridge\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"caption\":\"Jason Baldridge\"},\"sameAs\":[\"http:\\\/\\\/bcomposes.wordpress.com\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/pub\\\/jason-baldridge\\\/5\\\/629\\\/9b2\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/jasonbaldridge\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/jason-baldridge\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks","description":"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html","og_locale":"en_US","og_type":"article","og_title":"Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks","og_description":"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","og_url":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-10-05T21:47:00+00:00","article_modified_time":"2012-10-21T20:32:10+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","type":"image\/jpeg"}],"author":"Jason Baldridge","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/jasonbaldridge","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Jason Baldridge","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html"},"author":{"name":"Jason Baldridge","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0"},"headline":"Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API","datePublished":"2011-10-05T21:47:00+00:00","dateModified":"2012-10-21T20:32:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html"},"wordCount":1799,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","keywords":["Scala Tutorial"],"articleSection":["Scala"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html","url":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html","name":"Scala Tutorial - regular expressions, matching and substitutions with the scala.util.matching API - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","datePublished":"2011-10-05T21:47:00+00:00","dateModified":"2012-10-21T20:32:10+00:00","description":"PrefaceThis is part 6 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JVM Languages","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages"},{"@type":"ListItem","position":3,"name":"Scala","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages\/scala"},{"@type":"ListItem","position":4,"name":"Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0","name":"Jason Baldridge","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","caption":"Jason Baldridge"},"sameAs":["http:\/\/bcomposes.wordpress.com\/","http:\/\/www.linkedin.com\/pub\/jason-baldridge\/5\/629\/9b2","https:\/\/x.com\/http:\/\/twitter.com\/jasonbaldridge"],"url":"https:\/\/www.javacodegeeks.com\/author\/jason-baldridge"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=646"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/646\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/227"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}