3

Is it seamlessly possible to do?

 scala> val p = "$"
 scala> "hello, I have 65 dollars".replaceFirst("dollars", p)

Current result is

 java.lang.StringIndexOutOfBoundsException: String index out of range: 1
 ....

The expected result in scala 2.10:

 hello, I have 65 $

Problem is with variable p which stores symbol $, I need to process it as a string not regexp.

Note: I can't modify (e.g. replace all non-letter symbols) the p variable (only standard functions, e.g. .toString)

Note2: The given example is rather toy-example. I'd appreciate a more general solution. I.e. variable p can contain any type of content (symbols, numbers, text,...), therefore replacing "$" for "\\$" doesn.t make much sense

(this is improved version of similar problem: scala string, raw string )

3
  • Related stackoverflow.com/questions/12115187/replace-with Commented Apr 9, 2013 at 10:13
  • @om-nom-nom yes, I read it already, but there is replacement... Doesn't exist some method which would do the task without guessing what variable p can or can not contain in order not to get error? Commented Apr 9, 2013 at 10:17
  • @Jesper this is vary different question see note2 Commented Apr 9, 2013 at 13:15

3 Answers 3

2

Use Regex.quote for patterns and quoteReplacement for replacement strings. (These just call into Pattern.)

scala> import util.matching._
import util.matching._

scala> "hello, I have 65 dollars".replaceFirst("dollars", Regex quoteReplacement p)
res7: String = hello, I have 65 $

scala> "dollars".r replaceFirstIn ("hello, I have 65 dollars", Regex quoteReplacement p)
res8: String = hello, I have 65 $

scala> "hello, I have 65 dollars".replaceAllLiterally("dollars", p) // quotes both
res9: String = hello, I have 65 $
Sign up to request clarification or add additional context in comments.

Comments

2

You need to escape the dollar sign literal, because Java uses it in its implementation of regular expressions as a group reference.

You noted that you can't modify the string literal in the p variable, so you need to resort to replacing the dollar sign and other special characters like this:

Pattern.quote(p);

5 Comments

isn't there some other method how to do it? If not, what symbols do I have to replace? I'm aware of $ and \ -anything else? Variable p can contain everything(text, symbols, numbers,..) therefore I need to get rid of all "special characters"
Oh, I understood your question the wrong way. I thought you were just concerned with the dollar symbol. Updated my answer.
I wanted to put simple example - probably I'll edit it. Thanks for answer anyway
quote is interesting point, but I'll wait if something else will appear
I've tried your proposal, but it doesn't work: "i have 65 dollars".replaceFirst("dollars", Pattern.quote("$")) . gives Illegal group reference error
1

The problem is replaceFirst() uses regular expressions so:

"65 dollars".replaceFirst("dollars","$0") // compiles
"65 dollars".replaceFirst("dollars","$")  // throws "StringIndexOutOfBoundsException"

If,

val dollars = "$"

You could escape the $ symbol,

"65 dollars".replaceFirst( "dollars", if(dollars == "$") "\\$" else dollars )

or use string interpolation,

s"65 $dollars"

or go old school string manipulation,

val t = "65 dollars".split("dollars"); if(t.size>1) t.mkString(dollars) else t(0) + dollars

or with a map,

val ff = "dollars"
val r1 = "$"
"65 dollars, 3 dollars, 50 dollars".split(ff).zipWithIndex.map{case (t,0) => t+r1; case (t,_) => t+ff}.mkString

6 Comments

pls see my note2, i'm looking for some general solution, not just for $. That means I'm not willing to replace all possible escape and special characters ($,\,&,@, and who knows what else) but to treat the variable p like string instead of regexp
That's why I provided multiple solutions. You might try string interpolation. I upvoted your question because the $ symbol can be a "gotcha" unexpected error in regex.
thanks Keith, but still it is not the expected answer. e.g. if your variable dollars contains "\ " it will throw an error. Yes, you solved $ issue, but there can be similar problems with other symbols e.g. "\". As you stated replaceFirst takes its arugument as regexp - is it possible to change this "feature" into accepting string instead regexp. Or, use other "replaceFirst" function which would do the job?
I am not aware of a function that will parse a string to sanitize it for regex string replacements. If you don't use regex you still need do something about the lone backslash "\", as you discovered. Incidentally, replace() doesn't use regular expressions even though replaceFirst() does.
yes, replace and replaceAllLitarally works as needed. The only problem is that they replace all occurrences instead of just first one which I need. Thanks Keith!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.