LEARNING JAVASCRIPT - Trang 279

be a nice trick, it’s not required. Lookaheads are necessary whenever there is overlap‐

ping content, and they can simplify certain types of matching.
A classic example is validating that a password matches some policy. To keep it sim‐

ple, let’s say our password must contain at least one uppercase letter, number, and

lowercase letter, and no nonletter, nonnumber characters. We could, of course, use

multiple regexes:

function

validPassword

(

p

) {

return

/[A-Z]/

.

test

(

p

)

&&

// at least one uppercase letter

/[0-9]/

.

test

(

p

)

&&

// at least one number

/[a-z]/

.

test

(

p

)

&&

// at least one lowercase letters

!

/[^a-zA-Z0-9]/

.

test

(

p

);

// only letters and numbers

}

Let’s say we want to combine that into one regular expression. Our first attempt fails:

function

validPassword

(

p

) {

return

/[A-Z].*[0-9][a-z]/

.

test

(

p

);

}

Not only does this require the capital letter to come before the numbers to come

before the two lowercase letters, but we haven’t tested for the invalid characters at all.

And there’s really no sensible way to do it, either, because characters are consumed as

the regex is processed.
Lookaheads come to the rescue by not consuming input; essentially each lookahead is

an independent regex that doesn’t consume any input. Lookaheads in JavaScript look

like

(?=<subexpression>)

. They also have a “negative lookahead”:

(?!<subexpres

sion>)

will match only things that aren’t followed by the subexpression. Now we can

write a single regex to validate our passwords:

function

validPassword

(

p

) {

return

/(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z])(?!.*[^a-zA-Z0-9])/

.

test

(

p

);

}

You might be looking at this soup of letters and characters and thinking that our

multiregex function is better—or at least easier to read. And in this example, I would

probably agree. However, it demonstrates one of the important uses of lookaheads

(and negative lookaheads). Lookaheads definitely fall into the category of “advanced

regex,” but are important for solving certain problems.

Constructing Regexes Dynamically

We started off this chapter by saying that you should prefer the regex literal over the

RegExp

constructor. In addition to having to type four fewer letters, we prefer the

regex literal because we don’t have to escape backslashes as we do in JavaScript

strings. Where we do need to use the

RegExp

constructor is when we want to con‐

struct regexes dynamically. For example, you might have an array of usernames you

Constructing Regexes Dynamically | 255

Liên Kết Chia Sẽ

** Đây là liên kết chia sẻ bới cộng đồng người dùng, chúng tôi không chịu trách nhiệm gì về nội dung của các thông tin này. Nếu có liên kết nào không phù hợp xin hãy báo cho admin.