Skip to content

Commit 11cb359

Browse files
committed
Document regex replacement strings behavior.
All replacement methods use dolar signs to identify groups in the matched string, and backslashes to escape characters. Document this behavior, and provide a method that can be used to properly quote replacement strings when this behavior is not desired. Closes SI-4750.
1 parent 7c0a74a commit 11cb359

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

src/library/scala/util/matching/Regex.scala

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ import java.util.regex.{ Pattern, Matcher }
132132
*
133133
* @param regex A string representing a regular expression
134134
* @param groupNames A mapping from names to indices in capture groups
135+
*
136+
* @define replacementString
137+
* In the replacement String, a dollar sign (`$`) followed by a number will be
138+
* interpreted as a reference to a group in the matched pattern, with numbers
139+
* 1 through 9 corresponding to the first nine groups, and 0 standing for the
140+
* whole match. Any other character is an error. The backslash (`\`) character
141+
* will be interpreted as an escape character, and can be used to escape the
142+
* dollar sign. One can use [[scala.util.matching.Regex]]'s `quoteReplacement`
143+
* to automatically escape these characters.
135144
*/
136145
@SerialVersionUID(-2094783597747625537L)
137146
class Regex(regex: String, groupNames: String*) extends Serializable {
@@ -256,6 +265,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
256265
}
257266

258267
/** Replaces all matches by a string.
268+
*
269+
* $replacementString
259270
*
260271
* @param target The string to match
261272
* @param replacement The string that will replace each match
@@ -279,6 +290,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
279290
* val repl = datePattern replaceAllIn (text, m => m.group("month")+"/"+m.group("day"))
280291
* }}}
281292
*
293+
* $replacementString
294+
*
282295
* @param target The string to match.
283296
* @param replacer The function which maps a match to another string.
284297
* @return The target string after replacements.
@@ -297,13 +310,15 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
297310
* {{{
298311
* import scala.util.matching.Regex._
299312
*
300-
* val map = Map("x" -> "a var", "y" -> "another var")
313+
* val map = Map("x" -> "a var", "y" -> """some $ and \ signs""")
301314
* val text = "A text with variables %x, %y and %z."
302315
* val varPattern = """%(\w+)""".r
303-
* val mapper = (m: Match) => map get (m group 1)
316+
* val mapper = (m: Match) => map get (m group 1) map (quoteReplacement(_))
304317
* val repl = varPattern replaceSomeIn (text, mapper)
305318
* }}}
306319
*
320+
* $replacementString
321+
*
307322
* @param target The string to match.
308323
* @param replacer The function which optionally maps a match to another string.
309324
* @return The target string after replacements.
@@ -317,6 +332,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
317332
}
318333

319334
/** Replaces the first match by a string.
335+
*
336+
* $replacementString
320337
*
321338
* @param target The string to match
322339
* @param replacement The string that will replace the match
@@ -568,4 +585,18 @@ object Regex {
568585

569586
def replace(rs: String) = matcher.appendReplacement(sb, rs)
570587
}
588+
589+
/** Quotes replacement strings to be used in replacement methods.
590+
*
591+
* Replacement methods give special meaning to backslashes (`\`) and
592+
* dollar signs (`$`) in replacement strings, so they are not treated
593+
* as literals. This method escapes these characters so the resulting
594+
* string can be used as a literal replacement representing the input
595+
* string.
596+
*
597+
* @param text The string one wishes to use as literal replacement.
598+
* @return A string that can be used to replace matches with `text`.
599+
* @example {{{"CURRENCY".r.replaceAllIn(input, Regex quoteReplacement "US$")}}}
600+
*/
601+
def quoteReplacement(text: String): String = Matcher quoteReplacement text
571602
}

test/files/run/si4750.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
US$ 5.80

test/files/run/si4750.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.util.matching.Regex
2+
3+
object Test extends App {
4+
val input = "CURRENCY 5.80"
5+
println("CURRENCY".r.replaceAllIn(input, Regex quoteReplacement "US$"))
6+
}
7+

0 commit comments

Comments
 (0)