セールスフォースお助け隊ブログ | Salesforce
セールスフォース開発者のブログRSS
【Apex】Stringクラスの「replaceAll, replaceFirst」メソッドを利用するとエスケープしたはずの文字が元に戻ってしまう。

【Apex】Stringクラスの「replaceAll, replaceFirst」メソッドを利用するとエスケープしたはずの文字が元に戻ってしまう。

2011年2月21日 11:40

みなさんこんにちは。
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のファンページ

Yahoo!ブックマークに登録 Google ブックマーク はてなブックマーク Livedoorクリップ

← 前のエントリー     次のエントリー →

顧客管理システム Salesforce CRM