11

In Java regexes, you can use the intersection operator && in character classes to define them succinctly, e.g.

[a-z&&[def]]    // d, e, or f
[a-z&&[^bc]]    // a through z, except for b and c

Is there an equivalent in JavaScript?

7
  • 1
    Not seeing much point to the first example, as it's equivalent to [def]. Am I missing something? The second one makes sense (and is cool). Commented Jul 6, 2011 at 11:16
  • 1
    It wouldn't be much use anyway because JavaScript has limited shorthand character classes, and no Unicode support. I guess it might be useful for Unicode ranges, but it doesn't save much typing. What exactly do you need? Commented Jul 6, 2011 at 11:21
  • 1
    @Kobi: What do you mean "no Unicode support"? JavaScript uses Unicode natively (UTF-16, specifically) and supports Unicode escape sequences in regular expressions, including within character classes. Commented Jul 6, 2011 at 11:55
  • 1
    @TJ - I meant JavaScript's regular expressions, not JavaScript as a whole. It can't make 'אבג'.match(/\w+/) match (i.e. no /u flag), and doesn't have \p{L} shorthand character classes. You can define them yourself, of course, but that isn't fun. Commented Jul 6, 2011 at 11:59
  • @T.J.: I know what you mean about the first example - I guess they didn't want to distract us with usefulness? Commented Jul 6, 2011 at 13:15

4 Answers 4

12

Is there an equivalent in JavaScript?

Simple answer: no, there's not. It is specific Java syntax.

See: Regular Expressions Cookbook by Jan Goyvaerts and Steven Levithan. Here's a sneak-peek to the relevant section.

Probably needless to say, but the following JavaScript code:

if(s.match(/^[a-z]$/) && s.match(/[^bc]/)) { ... }

would do the same as the Java code:

if(s.matches("[a-z&&[^bc]]")) { ... }
Sign up to request clarification or add additional context in comments.

Comments

5

As others have said, there isn't an equivalent, but you can achieve the effect of && using a look-ahead. The transformation is:

[classA&&classB]

becomes:

(?=classA)classB

For instance, this in Java:

[a-z&&[^bc]]

has the same behavior as this:

(?=[a-z])[^bc]

which is fully supported in JavaScript. I don't know the relative performance of the two forms (in engines like Java and Ruby that support both).

Since the && operator is commutative, you can always use either side for the (positive or negative) look-ahead part.

Intersection of a class with a negated class can also be implemented with negative look-ahead. So the example above could also have been transformed to:

(?![bc])[a-z]

Comments

3

2023 answer: Yes, there is.

With the v flag:

[[a-z]&&[def]]
[[a-z]&&[^bc]]

Try them on regex101.com.

You can also do subtraction: [[a-z]--[bc]]. More information can be found on MDN.

2 Comments

It even works in my Opera. :D Still I'd hesitate to use this in production, better waiting some more years.
@bobblebubble Just like with any other new features in JS :) Babel does have good support for v, however.
1

You can get the same result as the Java regexes in JavaScript by writing out the character classes longhand, e.g.

Java           JavaScript   English
------------   ----------   -------
[a-z&&[def]]   [def]        d, e, or f
[a-z&&[^bc]]   [ad-z]       a through z, except for b and c

It’s just a bit more verbose/obscure in some circumstances, e.g.

Java               JavaScript
----------------   -----------
[A-Z&&[^QVX]]      [A-PR-UWYZ]
[A-Z&&[^CIKMOV]]   [ABD-HJLNP-UW-Z]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.