みなさんこんにちは。
Salesforceお助け隊の加藤です。
今回は、開発中に気付いた不可解な現象をご紹介します。
Stringクラスには、文字列置換処理を実行する以下の3つのメソッドが用意されています。
・replace
・replaceAll
・replaceFirst
上記のうち、「replaceAll, replaceFirst」メソッドの2つに関しては、
次のような不可解な現象が発生します。
例)
String sValue = '(1 OR 2)';
String sTarget = '1';
String sReplacement = String.escapeSingleQuotes('\'hoge\'');
String sResult1 = sValue.replace(sTarget, sReplacement);
String sResult2 = sValue.replaceAll(sTarget, sReplacement);
String sResult3 = sValue.replaceFirst(sTarget, sReplacement);
System.debug(sResult1);
System.debug(sResult2);
System.debug(sResult3);
上記のサンプルコードは、「(1 OR 2)」という文字列に対して、
「1」という文字を「\'hoge\'」に置換するというものです。
また、「\'hoge\'」に含まれるシングルクォートは、エスケープします。
※上記の処理は、SOQLインジェクション対策をイメージしてください。
その処理を、「replace, replaceAll, replaceFirst」で、
それぞれ実行すると以下のような結果が返されます。
・replaceメソッドの結果
→(\'hoge\' OR 2)
・replaceAll/replaceFirstメソッドの結果
→('hoge' OR 2)
このように、置換前に行ったはずのシングルクォートのエスケープが、
なかったことになってしまいます。
開発では、replaceFirstメソッドを使用しており、
なぜ、処理したはずのシングルクォートのエスケープが解除されるのか
原因がわからず嵌ってしまいました。
ちなみに、上記の問題への暫定的な対処方法としては、
以下のように、二重にシングルクォートのエスケープを掛けることにより対応しました。
String sValue = '(1 OR 2)';
String sTarget = '1';
String sReplacement = String.escapeSingleQuotes(String.escapeSingleQuotes('\'hoge\''));
String sResult = sValue.replaceFirst(sTarget, sReplacement);
System.debug(sResult);
SOQLの実行クエリを動的に生成する際に、上記の問題にぶつかるかもしれません。
その時は、この記事のことを思い出してみてください。
「セールスフォースお助け隊ブログ」へのコメントやご意見等ありましたら
ファンページまでお願いします。 Facebookのファンページ

