I am building a dynamic SOSL Query

searchText = 'AB-C';

searchquery = 'FIND {'+ searchText + '} IN all FIELDS RETURNING Account(   id, name, ownerid,website, CMFL__Oppty_Count__c WHERE '+ condition +'  order by  createddate DESC  )';


FIND {AB-C*} IN all FIELDS RETURNING Account( id, name,Additional_domains__c, ownerid,website WHERE (Website_Domain__c='ab\-c.com' OR Additional_domains__c like '%ab\-c.com%') order by createddate DESC )

When the query is run it returns an error

System.QueryException: line 1:8 mismatched character '-' expecting '}'

I thought i havent escaped the string for special chars and hence this error. I removed the '-' in AB-C and now i get this error on the where condition where i have escaped in the where conditions

Invalid string literal 'ab\-c.com'. Illegal character sequence '\-' in string literal.

When should i escape the string and when i should not while creating a dynamic query

2 Answers 2


The SOSL Reference describes the reserved characters in the search query (FIND clause):

The following characters are reserved: ? & | ! { } [ ] ( ) ^ ~ * : \ " ' + -

Reserved characters, if specified in a text search, must be escaped (preceded by the backslash \ character) to be properly interpreted. An error occurs if you do not precede reserved characters with a backslash. This is true even if the SearchQuery is enclosed in double quotes.

So you do need to escape the hyphen in your FIND clause with a backslash, which itself must be escaped (yielding \\-) in an Apex string literal.

In the SOSL WHERE clause, however, the hyphen is not a special character and does not need to be escaped.


According to the SOSL Reference mentioned by David Reed, this is a code snippet which should help in Java (using Apache Commons Text):

public class StringUtils {

     * Reserved characters which need to be escaped in SOSL
     * https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm
    public static final CharSequenceTranslator ESCAPE_SOSL;

    static {
        final Map<CharSequence, CharSequence> escapeSoslMap = new HashMap<>();
        escapeSoslMap.put("?", "\\?");
        escapeSoslMap.put("&", "\\&");
        escapeSoslMap.put("|", "\\|");
        escapeSoslMap.put("!", "\\!");
        escapeSoslMap.put("{", "\\{");
        escapeSoslMap.put("}", "\\}");
        escapeSoslMap.put("[", "\\[");
        escapeSoslMap.put("]", "\\]");
        escapeSoslMap.put("(", "\\(");
        escapeSoslMap.put(")", "\\)");
        escapeSoslMap.put("^", "\\^");
        escapeSoslMap.put("~", "\\~");
        escapeSoslMap.put("*", "\\*");
        escapeSoslMap.put(":", "\\:");
        escapeSoslMap.put("\\", "\\\\");
        escapeSoslMap.put("\"", "\\\"");
        escapeSoslMap.put("'", "\\'");
        escapeSoslMap.put("+", "\\+");
        escapeSoslMap.put("-", "\\-");
        ESCAPE_SOSL = new AggregateTranslator(new LookupTranslator(Collections.unmodifiableMap(escapeSoslMap)));

     * Escape SOSL reserved characters
     * https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm
    public static final String escapeSosl(final String input) {
        return ESCAPE_SOSL.translate(input);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.