36

According to the selectors docs, you must escape [ with double backslash, etc \\[.

I have a selector that is created like so (assume val attribute is something[4][2] in this example).

var val = $(this).attr('val');           

$select.find('option[value=' +  val + ']').show();

Can I write a regex to escape the brackets for me?

alex
  • 479,566
  • 201
  • 878
  • 984

7 Answers7

42

If you want something that works with any sort of value, try this:

var val = $(this).attr('val').replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\\\$&")

This works by escaping all CSS meta-characters listed on the Selectors page of the jQuery documentation with two backslashes.

Keep in mind that in your situation, there is no need to do something tricky like this. You can use the filter function to select all option elements with a given value without having to escape the value, as described in Mathias Bynens's answer.

Elias Zamaria
  • 96,623
  • 33
  • 114
  • 148
  • FYI, your expression is missing @ – Remi Despres-Smyth Jul 29 '13 at 13:56
  • I could swear I didn't see `@` on the selectors page when I wrote that, but I can't find exactly when they added it in the repository for their documentation. In any case, I am about to fix it. – Elias Zamaria Jul 30 '13 at 16:07
  • 2
    Doesn't work in my case (returns "Uncaught Error: Syntax error, unrecognized expression: Test \\# ") if I try to launch $(myString) – Kirk Hammett Jun 09 '15 at 10:32
  • 1
    i have this strange behavior: `> cs < "#XMTM2NDQwNTI5Mg\\=\\=" = $7 > $(cs) < Error: Syntax error, unrecognized expression: #XMTM2NDQwNTI5Mg\\=\\= > $("#XMTM2NDQwNTI5Mg\\=\\=") < m [
    ] (1) = $10` then i change the variable to one escape using:`replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\$&")`, using variable as a selector works.
    – danny Nov 19 '15 at 01:31
  • The replacement string "\\\\$&" doesn't work with jQuery 1.10. In that case, it should be "\\$&". – Vincent Ripoll Feb 19 '20 at 10:35
22

CSS character escape sequences (as used in selectors) are tricky. They’re so tricky I even made a web app that can tell you how to escape any character in CSS.

It’s much simpler and more efficient to simply select all option elements and then filter them based on their value attribute value:

var value = this.value;
$select.find('option').filter(function() {
  return this.value == value;
}).show();

That way, no special escaping is needed at all.

Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
7

Late to answer but,

jQuery 3

add the missing "" in 'option[value="'+ val +'"]'

var val = "something[4][2]";

$("select").find('option[value="' +  val  + '"]').show();
option{
  display: none;
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

<select>
  <option value="something[4][2]">4,2</option>
  <option value="something[1][1]">1,1</option>
</select>

jQuery 3 and jQuery.escapeSelector()

without wrapping quotes - so using your original selector 'option[value='+ val +']'

var val = "something[4][2]";           
var eSel = $.escapeSelector( val );    // something\[4\]\[2\]

$("select").find('option[value='+ eSel +']').show();
option{
  display: none;
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

<select>
  <option value="something[4][2]">4,2</option>
  <option value="something[1][1]">1,1</option>
</select>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
4

Check this out...

var val = $(this).attr('val').replace(/(\[|\])/g, '\\\\$1'); // something\\[4\\]\\[2\\]

of course, this only handles the brackets, not any other of the special characters. However, in my experience, the brackets are the only ones I use (because of PHP's handy way of handling input name attributes like these: something[])

alex
  • 479,566
  • 201
  • 878
  • 984
3

jQuery's FAQ has a nice solution for this that escapes all character that jQuery requires.

I like this nullsafe version of what they suggest:

function jqid (id) {
  return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1');
}
Valery Viktorovsky
  • 6,487
  • 3
  • 39
  • 47
theUtherSide
  • 3,338
  • 4
  • 36
  • 35
2

Put quotes around the attribute value in the selector, then you only have to escape backslashes and quotes in the value:

var val = $(this).attr('val');

val = val.replace(/\\/g, "\\\\").replace(/"/g, '\\"');

$select.find('option[value="' +  val + '"]').show();

If you know that the value doesn't have any backslashes or quotes (like in your example), then you don't need to escape anything in the value, you only need the quotes in the selector.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

If the selector ends with the special char, you can't escape it using double backslashes. The work arround is to use regex : For example, if the selector id is "bonus+" then you can use:

$("div[id$='bonus+']")

It makes more sense when you have dynamic selectors.

Mehdi Benmoha
  • 3,694
  • 3
  • 23
  • 43