0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript正規表現】`(?=.*[a-z])`って何?肯定先読みと`.*`を分解して理解する

0
Posted at

パスワードのバリデーションなどで、こんな正規表現を見かけることがあります。

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

最初に見たとき、特に分からなかったのが、

(?=.*[a-z])

の部分でした。

「.*は0文字以上なのに、どうして小文字があると判定できるんだろう?」

今回は、ここを一つずつ分解してみます。

(?=...)は「この先にある?」を確認する

(?=...)は**肯定先読み(Positive Lookahead)**と呼ばれます。

簡単に言うと、

「現在位置から先が、この条件を満たしているか?」

を確認する構文です。

特徴は、条件を確認しても文字列自体は読み進めないことです。

そのため、

(?=.*[a-z])
(?=.*[A-Z])
(?=.*[0-9])

のように並べて、

小文字がある?
大文字がある?
数字がある?

と複数の条件を確認できます。

.*は何をしている?

次に、

.*

を分解します。

. → 任意の1文字
* → 直前のパターンを0回以上繰り返す

つまり.*は、

「任意の文字が0文字以上続く」

という意味です。

そのため、

(?=.*[a-z])

は、

「途中に何文字あってもいいので、その先に小文字があるか?」

を確認しています。

小文字を要求しているのは.*ではなく、最後の[a-z]です。

なぜ.+ではなく.*?

ここも少し迷いました。

*と+には次の違いがあります。

* → 0回以上
+ → 1回以上

例えば、

^(?=.*[a-z])

なら、文字列の先頭が小文字でも、

.*    → 0文字
[a-z] → 先頭のa

として判定できます。

一方、.+にすると小文字の前に最低1文字必要になります。

「どこかに小文字があるか」を確認したいなら、0文字も許容する.*が適しています。

/^[a-z]+$/とは何が違う?

こちらも似ていますが意味は別です。

/^[a-z]+$/

これは、

「先頭から末尾まで、すべて小文字」

という条件です。

一方、

^(?=.*[a-z])

は、

「文字列のどこかに小文字が1文字以上ある」

という条件だけを確認します。

まとめ

(?=...) → この先が条件を満たすか確認
.       → 任意の1文字
*       → 0回以上
[a-z]   → 小文字1文字

つまり、

(?=.*[a-z])

は、

「この先のどこかに小文字があるか?」

という意味になります。

正規表現は丸ごと覚えようとすると難しいですが、記号を一つずつ分解すると、かなり理解しやすくなりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?