0

I did

temp = '(test)';
temp.match(temp);

and got back

0:'test'
1:'test'

Where did the parentheses go?

Update:

Tested in regexpal.com and found similar.

However, switching to {} did not have same concern.

Clarification

temp is "intended" to be a string. Not sure why it would be considered something else.

  • because "(test)" in interpreted as regular expression. – philipp Apr 07 '13 at 16:39
  • @philipp - `temp = '(test)'` I thought was creating a string. –  Apr 07 '13 at 16:41
  • 2
    "temp is "intended" to be a string. Not sure why it would be considered something else." - Because if you read the [String.match reference](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/match): "**Parameters**: *regexp*: A [regular expression](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp) object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using `new RegExp(obj)`. " – Fabrício Matté Apr 07 '13 at 16:42
  • 1
    I believe you could be able to use a regex escape function to solve the problem. Such as [this](http://stackoverflow.com/a/3561711/1331430) or [this](http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex). – Fabrício Matté Apr 07 '13 at 16:48

3 Answers3

2

Parentheses are metacharacters (specifically capturing parentheses) in regular expressions (note that if you pass a string to the match method it will be implicitly converted to a regular expression). You have to escape them if you want them to be taken literally (since you are dealing with a string, you also have to escape the escape character so that it will still exist when converted to a regex … and by then the regex won't match the original string).

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • Basically type conversion from String to Regexp where of course parentheses are special characters. –  Apr 14 '13 at 23:42
1

The argument to .match() is treated as a regular expression. Parentheses are meta-characters that mean something in that context. Specifically, they group portions of the matched string. Thus, your regular expression (test) matched the substring "test". The return value gives you the entire match as the first element of the array, and the first group as the second. In this case, because your group covered the whole matched substring, they're the same.

This is the sort of thing that the MDN documentation can quickly clear up:

Parameters

regexp
A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).

Community
  • 1
  • 1
Pointy
  • 371,531
  • 55
  • 528
  • 584
  • ... implicit conversion got me ... do you know what Felix King means in his first comment below? –  Apr 07 '13 at 17:09
  • I think he means that there's no way to make the exact same string with parentheses work as a regular expression to match itself in its entirety. – Pointy Apr 07 '13 at 17:31
0

You have to do this:

temp = '\(test\)';
temp.match(temp);

Since () define groups in Regex. look here for more info: http://www.regular-expressions.info/brackets.html

The () are characters used by regex. Just like .*[] etc. That's why it does not return the (). What I've done in the example above is escape them. So the Regex does not see it as a grouping.

Update:

it does work this way:

"(test)".match(/\(test\)/);

When you create a String and have a different Regex Object.

Niels
  • 44,106
  • 4
  • 55
  • 78
  • 3
    `'\(test\)'` has the same problem, since ``\`` is the escape character in strings as well (the resulting string is `(test)`). There is no way you can use the `( )` literally in the string and use the same string as expression to match itself (just tested it). – Felix Kling Apr 07 '13 at 16:42
  • @FelixKling doubling the backslash would do it: `\\(test\\)` but of course that's not the same string, as you say. – Pointy Apr 07 '13 at 16:43
  • @Pointy: But you cannot match the string with that. *edit:* Yeah, that's what I meant. The *expression* `\(test\)` does not match the *string* `\(test\)`. – Felix Kling Apr 07 '13 at 16:44
  • If your escaping ina regexp (`/\(test\)/` it will work fine, if your do ing this in a string you have to double escape: `"\\(test\\)"` – Sukima Apr 07 '13 at 16:44
  • @FelixKling ?? it'd match the string "(test)", no? Oh I see - it won't match itself. Yes I agree :-) – Pointy Apr 07 '13 at 16:45
  • Updated my answer, you are totally right, if you make an Regex object and a String, then it does work. – Niels Apr 07 '13 at 16:48
  • Re-phrasing Felix's comment, the \ is the escape characters inside strings as well, therefore `"\("` is an invalid escape sequence thus the parser ignores the \ and you get a string `"("`. You have to escape the escape character to be used inside a string literally. – Fabrício Matté Apr 07 '13 at 16:51
  • @livingston_mechanical: I was referring to Niels' proposed solution to escape the parenthesis with ``\(``. If you want to use a special regex character literally, you have to escape it. But in JavaScript (and many other languages) the backslash is the escape characters in strings as well. So, the string literal `'\(test\)'` does not produce an expression where `(` and `)` are escaped, it literally produces the same string as `'(test)'`, i.e. it is not a solution for the problem. – Felix Kling Apr 07 '13 at 17:20
  • @livingston_mechanical: To use a string with escaped special characters expression, you have to escape the backslash itself, i.e. the string literal `'\\(test\\)'` results in the string `\(test\)` which, if interpreted as expression, escapes the parenthesis properly. But now the string literally contains backslashes, while if treated as expression, the backslashes are special characters and not treated literally. Hence `"\\(test\\)".match("\\(test\\")` would not return a match. Does this help? It's all about meta-characters and in the context in which they are treated as such or literally. – Felix Kling Apr 07 '13 at 17:24