The pattern
attribute in the HTML <input>
element is a feature that validates whether a user's input matches a pre-defined regular expression pattern.
Webフォームでユーザーからの入力を制限・検証する方法として、HTMLの<input>
要素のpattern
属性は非常に便利です。
pattern
属性の基本pattern
属性は、フォームの送信前にユーザー入力が特定の正規表現パターンに一致するかどうかをチェックします。これにより、入力値の形式(例:メールアドレス、電話番号、郵便番号など)をあらかじめ定義し、不正な入力を防止できます。HTML
<input type="text" pattern="正規表現">
主にテキスト入力(type="text"
、type="search"
など)で使用されますが、その他の入力タイプ(例:type="tel"
など)でも利用できます。
数値入力(type="number"
)など一部のタイプでは、組み込みの検証が行われるため、pattern
属性は不要な場合があります。
pattern
属性pattern
属性は、JavaScriptなどで使用される正規表現とほぼ同じルールに従って記述されますが、入力値全体がそのパターンにマッチするかどうかを自動的にチェックする仕組みになっています。つまり、正規表現を記述するときに通常使う先頭のアンカー(^
)や末尾のアンカー($
)は、実際にはHTMLのpattern
属性では省略しても、ブラウザ側で入力全体に対してチェックが行われるため、暗黙的に適用されることになります。$
」を明示的に書いても、入力全体がパターンに合致するかどうかは同じ結果となり、省略しても問題ありません。しかし、正規表現の意味や意図をより明確に伝えるために、あえて「$
」を記述するケースもあります。これは、パターンの構造を見たときに、どこで文字列の終わりを意図しているのかがはっきりするというメリットがあります。^
」についても、明示的に書くことは可能です。明示することで、パターンの開始位置が文字列の最初であることを示し、意図をより分かりやすくする効果があります。ただし、HTMLのpattern
属性では先頭と末尾が自動的にチェック対象になるため、実際の動作としては先頭と末尾のアンカーを省略しても、入力全体がパターンに一致するかどうかの検証結果は変わりません。初心者の方にとっては、これらのアンカーを明示するかどうかは「書くか書かないかのスタイルの違い」であり、どちらを使っても基本的な検証機能に違いはないと理解していただければよいでしょう。<input type="text" pattern="[A-Za-z]{3,}">
は、少なくとも3文字の英字のみの入力を要求します。以下は、メールアドレスを正規表現でチェックし、正しければ画面に表示する最もシンプルなサンプルコードです。
HTML
<label for="email">メールアドレス:</label>
<input type="email" id="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" required>
<button onclick="validate()">送信</button>
<p id="result"></p>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
function validate() {
const emailInput = document.getElementById('email');
const email = emailInput.value;
const regex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/;
const resultEl = document.getElementById('result');
if (regex.test(email)) {
resultEl.textContent = '有効なメールアドレス : ' + email;
} else {
resultEl.textContent = '無効なメールアドレスです。';
}
}
このコードでは、ユーザーがメールアドレスを入力して「送信」ボタンを押すと、JavaScriptのvalidate()
関数が呼ばれ、正規表現で入力値を検証し、有効な場合はそのメールアドレスを表示します。
以下の正規表現は、メールアドレスの形式を検証するためのもので、各部分は以下のような意味を持ちます。
HTML
^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$
^
[a-z0-9._%+-]+
@
より前の部分)を表します。a-z
)、数字 (0-9
)、ピリオド (.
)、アンダースコア (_
)、パーセント (%
)、プラス (+
)、ハイフン (-
)です。]
の後ろの +
は、これら []
内で示した文字が1文字以上連続している必要があることを意味します。@
@
」です。[a-z0-9.-]+
@
の後、トップレベルドメインの直前の部分)を表します。a-z
)、数字 (0-9
)、ピリオド (.
)、ハイフン (-
)です。]
の後ろの +
は、これら []
内で示した文字が1文字以上連続している必要があることを意味します。\.
.
」を表します。[a-z]{2,}
[a-z]
は小文字の英字のみを許容し、{2,}
は2文字以上でなければならないことを示します。$
この正規表現全体で、メールアドレスが先頭から末尾まで正確にこのパターンに従っているかをチェックし、不正な形式の入力を防ぐ仕組みとなっています。
以下は、電話番号(例: "090-1234-5678")を正規表現でチェックし、正しければその番号を表示する最もシンプルなサンプルコードです。電話番号の入力には、pattern
属性で「2~4桁-2~4桁-3~4桁」の形式を指定しています。
HTML
<label for="phone">電話番号 (例: 090-1234-5678):</label>
<input type="tel" id="phone" name="phone" pattern="\d{2,4}-\d{2,4}-\d{3,4}" required>
<button onclick="validate2()">送信</button>
<p id="result2"></p>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
function validate2() {
const phoneInput = document.getElementById('phone');
const phone = phoneInput.value;
// pattern属性と同じ正規表現をJavaScriptでも使用
const regex = /^\d{2,4}-\d{2,4}-\d{3,4}$/;
const resultEl = document.getElementById('result2');
if (regex.test(phone)) {
resultEl.textContent = '有効な電話番号 : ' + phone;
} else {
resultEl.textContent = '無効な電話番号です。';
}
}
このコードでは、ユーザーが電話番号を入力し「送信」ボタンを押すと、JavaScriptのvalidate2()
関数が呼ばれ、入力値が正規表現にマッチしているかをチェックします。正しい形式の場合は画面にその番号が表示され、不正な場合はエラーメッセージが表示されます。
以下の正規表現は、電話番号が「数字(2~4桁)-数字(2~4桁)-数字(3~4桁)」という形式になっているかを検証するためのものです。各部分の意味は以下のとおりです。
HTML
/^\d{2,4}-\d{2,4}-\d{3,4}$/
^
\d{2,4}
\d
は任意の数字(0〜9
)を意味し、{2,4}
はその数字が2桁以上4桁以下連続していることを表します。これが最初の数字の部分(例:"090"
や "03"
など)に対応します。-
\d{2,4}
"1234"
や "123"
など)。-
\d{3,4}
"5678"
や "678"
など)に該当します。$
このように、正規表現全体は、入力された電話番号が必ず先頭から末尾まで、指定した「桁数」と「ハイフンによる区切り」を正確に守っているかどうかをチェックします。もしこのパターンに一致すれば、有効な形式と判断され、そうでなければエラーメッセージが表示される仕組みになっています。
ブラウザが自動で生成するエラーメッセージは十分でない場合があります。title
属性を使って、ユーザーに対してどのような入力が期待されているかを明示するとよいでしょう。
HTML
<input type="text" pattern="\d{4}" title="4桁の数字を入力してください" required>
ここのサンプルではテキストボックスにカーソルを当てるとtitle
属性に入力した文字列(4桁の数字を入力してください)が表示されます。
JavaScriptと組み合わせることで、入力中にフィードバックを表示するなど、ユーザーエクスペリエンスをさらに向上させることが可能です。たとえば、oninput
イベントを利用して、入力がパターンに合致しているかを確認し、メッセージを表示するなどの方法があります。
以下は、メールアドレス入力欄でリアルタイムに入力の妥当性をチェックし、フィードバックを表示する最もシンプルなサンプルコードです。
HTML
<label for="email2">メールアドレス:</label>
<input type="email" id="email2" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" required oninput="checkEmail()">
<p id="feedback"></p>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
function checkEmail() {
const emailInput2 = document.getElementById('email2');
const feedback = document.getElementById('feedback');
// HTMLのバリデーション機能を利用
if (emailInput2.validity.valid) {
feedback.textContent = "正しいメールアドレスです。";
} else {
feedback.textContent = "無効なメールアドレスです。";
}
}
このコードでは、oninput
イベントを利用して、ユーザーが入力するたびにcheckEmail()
関数が実行され、ブラウザの組み込みバリデーション(validity
プロパティ)を使って入力値がパターンに合致しているかをリアルタイムでチェックし、その結果を画面に表示します。
正規表現の高度な機能(グループ化、量指定子、オプションなど)を使うことで、より複雑な入力検証が可能です。
例 : 郵便番号(例: "123-4567" または "1234567" の両方を許可する)
HTML
<input type="text" pattern="\d{3}-?\d{4}" title="郵便番号は「123-4567」または「1234567」の形式で入力してください" required>
ここでの正規表現 \d{3}-?\d{4}
は、主に7桁の数字の中で、3桁と4桁の間にハイフンがあってもなくても良いというパターンを表しています。各部分を詳しく解説すると、以下のようになります。
\d{3}
\d
は数字(0〜9
)を意味します。{3}
はその数字が「ちょうど3回」繰り返されることを指定しています。123
」など。-?
-
)そのものを表します。?
は直前の文字が「0回または1回」現れることを意味し、ハイフンがあってもなくても良いという条件を示しています。-
」があっても「1234567
」のようにハイフンがなくても良い。\d{4}
\d
は数字を意味し、{4}
は「ちょうど4回」数字が連続していることを指定します。4567
」など。この正規表現全体で、「1234567
」や「123-4567
」のような形式にマッチします。つまり、最初の3桁の数字の後にハイフンが0個または1個あり、続けて4桁の数字が並ぶパターンを検証するために使われます。
これらのテクニックを使うと、特定の条件下でのみ入力を許可する、といった高度な検証が可能になります。ただし、正規表現が複雑になるため、メンテナンス性や可読性を考慮する必要があります。
大文字、小文字、数字、特殊文字を含む8文字以上のパスワードを要求する場合の例です。
HTML
<label for="password">パスワード:</label>
<input type="password" id="password" name="password"
pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}"
title="パスワードは8文字以上で、大文字、小文字、数字、特殊文字をそれぞれ1文字以上含む必要があります。" required>
ここでの正規表現は、パスワードの強度をチェックするためによく使われるパターンで、以下の条件を全て満たす必要があります。
HTML
(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}
(?=.*[a-z])
.*
は任意の文字(改行を除く)が0文字以上続くことを意味します。[a-z]
は小文字のアルファベットが少なくとも1文字含まれていることを確認します。(?=.*[A-Z])
[A-Z]
により大文字が1文字以上含まれているかを検証します。(?=.*\d)
\d
は数字(0〜9
)を表します。(?=.*[\W_])
\W
は「単語文字(アルファベット、数字、アンダースコア)以外の文字」、つまり記号やスペースなどを意味します。_
)は通常単語文字に含まれるため、ここでは明示的に含めるために [\W_]
としています。.{8,}
.
)は改行を除く任意の1文字を表します。{8,}
はその直前の要素が8文字以上続く必要があることを意味します。この正規表現は、「小文字、大文字、数字、記号(またはアンダースコア)の各要素を1つ以上含み、かつ全体で8文字以上の文字列」であることを検証します。これにより、パスワードとして一定以上の強度が求められる条件を満たしているかどうかをチェックすることができます。
正規表現における肯定の先読み(Positive Lookahead)は、ある位置から先に特定のパターンが存在するかどうかを確認するための構文です。具体的には、(?=パターン)
という形式で記述され、次のような特徴があります。
(?=.*[a-z])
と記述します。ここで、.*
は任意の文字が0文字以上続くことを意味し、その後に[a-z]
が来ることで「どこかに小文字が存在する」ことを確認しています。(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}
という正規表現を適用する場合、(?=.*[a-z])
は「a, s, s」などの小文字が存在するかを確認し、(?=.*[A-Z])
は「P」の存在を確認し、(?=.*\d)
は「1, 2, 3」の存在を確認し、(?=.*[\W_])
は「!」が存在するかを確認します。.{8,}
で8文字以上であることも確認され、マッチと判断されます。まとめると、肯定の先読みは、正規表現で複数の条件を同時に満たしているかを検証するための強力なツールであり、マッチングの過程で実際の文字列を「消費」せずに条件確認だけを行う点が特徴です。
pattern
属性はほとんどの最新ブラウザでサポートされていますが、ブラウザごとの実装の差異やユーザー設定により、エラーメッセージの表示や動作が異なる場合があります。
※ そのため、JavaScriptによる補完検証を併用するのが望ましい場合もあります。
あまりにも厳格なパターンを設定すると、正当な入力まで拒否してしまう可能性があります。ユーザーがどのような入力を行うかを十分に考慮し、柔軟なパターンを設計することが重要です。
エラーが発生した際の表示方法を工夫し、スクリーンリーダーなどを利用するユーザーにもわかりやすいエラーメッセージを提供しましょう。
pattern
属性による検証はクライアント側で行われるため、セキュリティ対策としては不十分です。必ずサーバー側でも入力の検証とサニタイズを行い、悪意ある入力を防ぐことが必要です。
複雑な正規表現を作成する際は、オンラインの正規表現チェッカー(例:regex101.comなど)を利用して、パターンの動作確認を行うと良いでしょう。これにより、意図しないマッチや漏れを事前に発見できます。
JavaScriptやサーバーサイドの言語では、正規表現にコメントを入れることができる「拡張モード(xフラグ)」が利用できます。HTMLのpattern
属性では直接コメントは使えませんが、ドキュメントやコード内のコメントとして解説を残すと保守性が向上します。
jQuery Validation Pluginなどのライブラリは、HTMLのpattern
属性による検証と連動して、よりリッチなユーザーインターフェースのフィードバックを提供します。これらを活用することで、エラーメッセージのカスタマイズや、複数項目の同時検証が容易になります。
HTMLだけでなく、JavaScriptで独自のバリデーションロジックを追加する場合、pattern
属性で基本チェックを行い、さらに細かい条件についてはJavaScriptで検証するというハイブリッドなアプローチが効果的です。
HTMLの<input pattern>
属性は、Webフォームでのユーザー入力のフォーマットを簡単に制限・検証するための強力なツールです。
また、pattern
属性によるクライアント側検証はあくまで補助的なものであり、サーバー側での検証との併用が必須です。ユーザーエクスペリエンスとセキュリティの両面から最適なフォーム設計を目指しましょう。