JavaScriptの正規表現は、テキストのパターンマッチングや操作を行うための強力なツールです。特に、複雑な文字列操作をシンプルに実現するために、JavaScriptのRegExpオブジェクトを活用することが重要です。本記事では、正規表現の基礎から始まり、応用的な使い方や具体的なコード例を通じて、正規表現を使いこなすための知識を提供します。初心者から上級者まで、どのレベルのプログラマーにも役立つ内容を網羅していますので、ぜひ最後までお読みください。
RegExpオブジェクトの概要
JavaScriptにおけるRegExpオブジェクトは、文字列内で特定のパターンを検索、置換、抽出するために使用される正規表現の実装です。RegExpオブジェクトは、特定の文字列パターンを表現するための形式であり、プログラム内でテキストデータの検証や操作を効率的に行うことができます。正規表現は、通常の文字列操作に比べて柔軟かつ強力であり、複雑な文字列パターンを簡潔に表現する手段を提供します。
基本的な構造と生成方法
JavaScriptでRegExpオブジェクトを生成する方法は主に2つあります。1つ目はリテラル構文を使う方法で、スラッシュで囲まれた形式で記述します。2つ目はコンストラクタを使う方法で、new RegExp()
と記述します。
// リテラル構文を使用する例
let regexLiteral = /abc/;
// コンストラクタを使用する例
let regexConstructor = new RegExp("abc");
これらの基本的な構造を理解することで、正規表現を利用した高度な文字列操作を始めるための土台が築かれます。
正規表現の基本構文
正規表現の基本構文は、文字列内で特定のパターンを表現するためのルールを定義します。これらの構文を理解することで、正規表現を使って複雑な文字列操作が可能になります。ここでは、正規表現の最も基本的な構文要素を紹介します。
文字リテラル
文字リテラルは、パターンにそのままマッチする文字列を指定します。たとえば、/cat/
は文字列「cat」と完全に一致する部分を探します。
let regex = /cat/;
console.log(regex.test("The cat is on the roof.")); // true
特殊文字
特殊文字は、特定の意味を持つ記号です。たとえば、.
は任意の一文字にマッチします。*
は直前の文字が0回以上出現する場合にマッチします。
let regexDot = /c.t/;
console.log(regexDot.test("cut")); // true
console.log(regexDot.test("cat")); // true
let regexStar = /ca*t/;
console.log(regexStar.test("ct")); // true
console.log(regexStar.test("cat")); // true
console.log(regexStar.test("caaaaat")); // true
文字クラス
文字クラスは、特定の文字集合にマッチするための構文です。[abc]
のように使用し、a
またはb
またはc
のいずれか一文字にマッチします。
let regexClass = /c[aeiou]t/;
console.log(regexClass.test("cat")); // true
console.log(regexClass.test("cot")); // true
console.log(regexClass.test("cut")); // true
アンカー
アンカーは、文字列の特定の位置にマッチさせるために使用します。^
は文字列の先頭に、$
は文字列の末尾にマッチします。
let regexStart = /^cat/;
console.log(regexStart.test("cat is here.")); // true
console.log(regexStart.test("There is a cat.")); // false
let regexEnd = /cat$/;
console.log(regexEnd.test("There is a cat")); // true
console.log(regexEnd.test("cat is here.")); // false
エスケープシーケンス
特殊文字をリテラルとして使用したい場合は、バックスラッシュ\
を使ってエスケープします。例えば、.
をリテラルとして使用する場合、/a\.b/
のように書きます。
let regexEscape = /a\.b/;
console.log(regexEscape.test("a.b")); // true
console.log(regexEscape.test("acb")); // false
これらの基本構文を理解することで、正規表現の基礎を固めることができます。この知識は、さらに複雑なパターンマッチングを行う際に役立ちます。
マッチングパターンの詳細
正規表現を効果的に活用するためには、さまざまなマッチングパターンを理解しておくことが重要です。これらのパターンは、特定の条件に一致する文字列を柔軟に検索するためのものです。ここでは、よく使われるマッチングパターンについて詳しく説明します。
量指定子
量指定子は、特定の文字やグループがどれくらいの回数出現するかを指定するために使用されます。これにより、より柔軟なパターンを定義できます。
*
:直前の文字が0回以上出現する+
:直前の文字が1回以上出現する?
:直前の文字が0回または1回出現する{n}
:直前の文字がちょうどn回出現する{n,m}
:直前の文字がn回からm回出現する
let regexStar = /a*/;
console.log("aaa".match(regexStar)); // ["aaa"]
let regexPlus = /a+/;
console.log("aa".match(regexPlus)); // ["aa"]
let regexQuestion = /a?/;
console.log("aaa".match(regexQuestion)); // ["a"]
let regexExact = /a{3}/;
console.log("aaaa".match(regexExact)); // ["aaa"]
let regexRange = /a{2,4}/;
console.log("aaaa".match(regexRange)); // ["aaaa"]
グループ化とキャプチャ
グループ化は、複数の要素をまとめて扱うために使用されます。また、キャプチャグループを使用すると、マッチした部分を後で再利用したり、取得したりすることが可能です。
(abc)
:abc
にマッチし、キャプチャグループとして記憶される(?:abc)
:abc
にマッチするが、キャプチャされない
let regexGroup = /(abc)/;
let result = "abcabc".match(regexGroup);
console.log(result); // ["abc", "abc"]
let regexNonCapture = /(?:abc)/;
let resultNonCapture = "abcabc".match(regexNonCapture);
console.log(resultNonCapture); // ["abc"]
オルタネーション(または)
オルタネーションは、複数の選択肢のいずれかにマッチさせるために使用します。|
を使って、選択肢を区切ります。
let regexOr = /cat|dog/;
console.log("I have a cat.".match(regexOr)); // ["cat"]
console.log("I have a dog.".match(regexOr)); // ["dog"]
先読みと後読み
先読みと後読みは、特定のパターンの前後にある文字列を条件としてマッチさせるために使用します。これにより、より細かい制御が可能になります。
(?=abc)
:abc
の前にあるパターンにマッチ(?!abc)
:abc
の前にないパターンにマッチ(?<=abc)
:abc
の後にあるパターンにマッチ(?<!abc)
:abc
の後にないパターンにマッチ
let regexLookahead = /a(?=b)/;
console.log("abc".match(regexLookahead)); // ["a"]
let regexLookbehind = /(?<=a)b/;
console.log("ab".match(regexLookbehind)); // ["b"]
これらのマッチングパターンを駆使することで、より複雑な検索や操作を行うことが可能になります。正規表現の柔軟性を高めるためには、これらのパターンを理解し、適切に活用することが不可欠です。
正規表現を使った文字列操作
JavaScriptの正規表現を使って、文字列内でパターンマッチングを行うだけでなく、さまざまな操作を効率的に実行することができます。ここでは、文字列の検索、置換、分割、抽出など、正規表現を用いた代表的な文字列操作について解説します。
文字列の検索
正規表現を使って、文字列内で特定のパターンを検索する方法はいくつかあります。もっとも一般的な方法はtest
メソッドとexec
メソッドです。
test
メソッド:指定したパターンが文字列に存在するかどうかを調べ、結果を真偽値で返します。
let regex = /dog/;
console.log(regex.test("I have a dog.")); // true
console.log(regex.test("I have a cat.")); // false
exec
メソッド:指定したパターンが見つかった場合、その詳細情報を含む配列を返します。見つからない場合はnull
を返します。
let regex = /dog/;
let result = regex.exec("I have a dog.");
console.log(result); // ["dog"]
文字列の置換
文字列内の特定のパターンを置換するには、replace
メソッドを使用します。正規表現を使うことで、複雑な置換処理も簡単に行えます。
let text = "The sky is blue.";
let regex = /blue/;
let newText = text.replace(regex, "green");
console.log(newText); // "The sky is green."
正規表現を使うと、複数のパターンを一度に置換したり、パターンに基づいて部分的に置換したりすることが可能です。また、キャプチャグループを利用して、置換の際にキャプチャした部分を再利用することもできます。
let text = "2024-08-15";
let regex = /(\d{4})-(\d{2})-(\d{2})/;
let newText = text.replace(regex, "$2/$3/$1");
console.log(newText); // "08/15/2024"
文字列の分割
正規表現を使って、文字列を特定のパターンで分割するには、split
メソッドを使用します。これにより、複雑な分割条件を簡単に指定できます。
let text = "apple, banana, cherry";
let regex = /,\s*/;
let fruits = text.split(regex);
console.log(fruits); // ["apple", "banana", "cherry"]
文字列の抽出
文字列から特定のパターンに一致する部分を抽出するには、match
メソッドを使用します。複数の一致を取得したい場合は、g
フラグを使用することで、すべての一致部分を配列として取得できます。
let text = "The price is $5.99, and the tax is $0.99.";
let regex = /\$\d+\.\d{2}/g;
let prices = text.match(regex);
console.log(prices); // ["$5.99", "$0.99"]
これらの方法を組み合わせることで、複雑な文字列操作を効率的に行うことができます。正規表現を活用した文字列操作は、データの解析や加工を行う際に非常に役立ちます。正規表現を正しく理解し、適切に使用することで、コードの柔軟性と効率が大幅に向上します。
フラグの利用と動作
JavaScriptの正規表現には、検索や操作の動作を制御するための「フラグ」がいくつか用意されています。これらのフラグを理解し、適切に使用することで、正規表現の柔軟性とパワーが大幅に向上します。ここでは、主要なフラグとその効果について詳しく説明します。
主要なフラグの種類
g
(global)g
フラグは、文字列全体を対象にして、パターンに一致するすべての部分を検索します。通常、g
フラグがない場合、最初に一致した部分だけが対象となります。
let regex = /cat/g;
let text = "The cat chased another cat.";
let matches = text.match(regex);
console.log(matches); // ["cat", "cat"]
i
(ignore case)i
フラグは、大文字と小文字を区別せずに検索を行います。これにより、文字のケースに関係なく一致を確認できます。
let regex = /cat/i;
let text = "The Cat chased a dog.";
let result = regex.test(text);
console.log(result); // true
m
(multiline)m
フラグは、文字列を複数行として扱います。これにより、^
や$
のアンカーが各行の先頭と末尾にマッチするようになります。
let regex = /^cat/m;
let text = "dog\ncat\nmouse";
let matches = text.match(regex);
console.log(matches); // ["cat"]
s
(dotAll)s
フラグは、ドット(.
)が改行文字にもマッチするようにします。通常、ドットは改行を除く任意の文字にマッチしますが、このフラグを使うと改行も含めて任意の文字にマッチさせることができます。
let regex = /cat.*dog/s;
let text = "cat\nis chasing a\ndog";
let result = regex.test(text);
console.log(result); // true
y
(sticky)y
フラグは、文字列の指定位置から一致する部分を探します。このフラグがある場合、一致は文字列の現在の位置に固執します。
let regex = /cat/y;
let text = "catcat";
regex.lastIndex = 3;
let result = regex.test(text);
console.log(result); // true
u
(unicode)u
フラグは、正規表現がUnicodeコードポイントでのマッチングをサポートするようにします。これにより、サロゲートペアを含む文字や特定のUnicodeシーケンスに対応できるようになります。
let regex = /\u{1F600}/u;
let text = "😀 is a smiley face.";
let result = regex.test(text);
console.log(result); // true
フラグの組み合わせ使用
フラグは組み合わせて使用することもできます。例えば、/cat/gi
のようにすることで、「cat」に一致するすべての部分を、大文字小文字を区別せずに検索できます。
let regex = /cat/gi;
let text = "Cat and cat are here.";
let matches = text.match(regex);
console.log(matches); // ["Cat", "cat"]
フラグを効果的に利用することで、正規表現の適用範囲と操作の精度を高めることができます。フラグの組み合わせを理解し、適切に活用することは、正規表現を使いこなすための重要なスキルです。
具体例と応用シナリオ
正規表現は、単純な文字列検索や置換だけでなく、実際のアプリケーション開発においても非常に有用です。ここでは、JavaScriptの正規表現を使用した具体的なコード例と応用シナリオを紹介し、実際にどのように利用できるかを解説します。
メールアドレスのバリデーション
ウェブフォームなどで入力されたメールアドレスが正しい形式であるかを確認するために、正規表現を使うことができます。以下は、一般的なメールアドレス形式をチェックするための正規表現の例です。
let emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
let email = "user@example.com";
let isValidEmail = emailRegex.test(email);
console.log(isValidEmail); // true
この正規表現は、@
記号の前後に適切な文字があり、最後にドメイン名があるかどうかをチェックします。
電話番号のフォーマット変更
正規表現を使って、ユーザーが入力した電話番号を特定のフォーマットに変換することができます。例えば、数字のみで入力された電話番号を、ハイフンで区切られた形式に変更します。
let phoneRegex = /(\d{3})(\d{3})(\d{4})/;
let phone = "1234567890";
let formattedPhone = phone.replace(phoneRegex, "$1-$2-$3");
console.log(formattedPhone); // "123-456-7890"
このコードでは、10桁の数字を3-3-4の形式で分割し、ハイフンで結合しています。
HTMLタグの除去
テキストデータからHTMLタグを取り除く場合にも、正規表現が役立ちます。以下の例では、HTMLタグをすべて削除し、純粋なテキストだけを残す処理を行います。
let htmlRegex = /<[^>]*>/g;
let htmlString = "<p>This is a <strong>bold</strong> text.</p>";
let plainText = htmlString.replace(htmlRegex, "");
console.log(plainText); // "This is a bold text."
この正規表現は、<
と>
の間にあるすべての文字をタグとみなし、削除します。
URLのパースとクエリパラメータの取得
ウェブアプリケーションでは、URLからクエリパラメータを抽出する必要がある場合があります。正規表現を使って、URLから特定のパラメータを簡単に取り出すことができます。
let url = "https://example.com/page?param1=value1¶m2=value2";
let paramRegex = /[?&]([^=#]+)=([^&#]*)/g;
let params = {};
let match;
while ((match = paramRegex.exec(url)) !== null) {
params[match[1]] = match[2];
}
console.log(params); // { param1: "value1", param2: "value2" }
このコードでは、クエリ文字列内のすべてのパラメータを抽出し、それらをオブジェクトとして保存しています。
高度なテキスト処理:MarkdownからHTMLへの変換
Markdown形式のテキストをHTMLに変換する場合、正規表現を使って見出しやリンクなどをHTMLタグに変換できます。以下は簡単なMarkdownの見出しをHTMLに変換する例です。
let markdown = "# Heading 1\n## Heading 2\n### Heading 3";
let html = markdown
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
.replace(/^# (.*$)/gim, '<h1>$1</h1>');
console.log(html);
// "<h1>Heading 1</h1><h2>Heading 2</h2><h3>Heading 3</h3>"
この例では、Markdownの見出しをHTMLの<h1>
、<h2>
、<h3>
タグに変換しています。
これらの具体例を通じて、正規表現がさまざまな場面でどれほど強力で便利かを理解できたと思います。正規表現を駆使することで、日常的なテキスト処理を効率よく実行できるようになります。
高度な正規表現テクニック
正規表現には、基本的な検索や置換だけでは対応できない、より複雑なパターンマッチングが必要な場面があります。ここでは、正規表現の高度なテクニックについて解説し、特定のシナリオに対処する方法を紹介します。これらの技術を使いこなすことで、さらに強力な文字列操作が可能になります。
後方参照(Backreferences)
後方参照は、正規表現内でキャプチャグループを参照する機能です。これにより、同じ内容が繰り返されるパターンを見つけることができます。例えば、同じ単語が連続して現れるパターンを検出することができます。
let regex = /\b(\w+)\s+\1\b/;
let text = "This is is a test test.";
let matches = text.match(regex);
console.log(matches); // ["is is", "is"]
この正規表現は、単語の間にスペースがあり、同じ単語が連続している部分を検出します。
ルックアヘッド(Lookahead)
ルックアヘッドは、特定のパターンの直後に別のパターンが続くかどうかを確認するために使用します。これにより、パターンが一致するかどうかを決定する際に、次に続く文字列の内容を考慮できますが、実際にはその部分をマッチ結果に含めません。
- 肯定のルックアヘッド:
(?=...)
次に続く部分が指定したパターンに一致する場合にのみ、前の部分をマッチさせます。
let regex = /\d+(?= dollars)/;
let text = "I have 100 dollars.";
let match = text.match(regex);
console.log(match); // ["100"]
- 否定のルックアヘッド:
(?!...)
次に続く部分が指定したパターンに一致しない場合にのみ、前の部分をマッチさせます。
let regex = /\d+(?! dollars)/;
let text = "I have 100 euros.";
let match = text.match(regex);
console.log(match); // ["100"]
ルックビハインド(Lookbehind)
ルックビハインドは、特定のパターンの前に別のパターンが存在するかどうかを確認するために使用します。これにより、前に続く文字列の内容に基づいてマッチングを行いますが、その部分を実際のマッチ結果に含めません。
- 肯定のルックビハインド:
(?<=...)
前に続く部分が指定したパターンに一致する場合にのみ、その後の部分をマッチさせます。
let regex = /(?<=\$)\d+/;
let text = "The price is $100.";
let match = text.match(regex);
console.log(match); // ["100"]
- 否定のルックビハインド:
(?<!...)
前に続く部分が指定したパターンに一致しない場合にのみ、その後の部分をマッチさせます。
let regex = /(?<!\$)\d+/;
let text = "The cost is 100 dollars.";
let match = text.match(regex);
console.log(match); // ["100"]
ネストされたグループの処理
ネストされたグループを使用すると、より複雑なパターンを定義できます。ネストされたグループは、外側のグループと内側のグループの両方に一致する部分を検出します。
let regex = /(\d{4})-(\d{2})-(\d{2})/;
let text = "Date: 2024-08-15";
let matches = text.match(regex);
console.log(matches); // ["2024-08-15", "2024", "08", "15"]
この正規表現では、日付形式に一致する文字列全体をキャプチャし、その中の年、月、日も個別にキャプチャしています。
動的正規表現
正規表現を動的に作成することで、ユーザー入力や他の変数に基づいてパターンを柔軟に変更することができます。これにより、さまざまな条件に対応したパターンマッチングが可能になります。
let pattern = "cat";
let regex = new RegExp(pattern, "i");
let text = "I have a Cat.";
let match = text.match(regex);
console.log(match); // ["Cat"]
この例では、変数pattern
に基づいて正規表現が動的に生成され、大文字小文字を区別しない検索が行われています。
これらの高度なテクニックを使いこなすことで、正規表現を利用した文字列操作の幅がさらに広がります。これらの機能を理解し、適切に活用することで、より精度の高いデータ解析やテキスト処理が可能となります。
パフォーマンスの考慮
正規表現は非常に強力なツールですが、使用方法によってはパフォーマンスに影響を与える可能性があります。特に、大規模なデータセットや複雑なパターンを処理する場合、正規表現のパフォーマンスを最適化することが重要です。ここでは、正規表現を使用する際のパフォーマンスに関する考慮事項と最適化の方法について解説します。
不要なグループ化の回避
キャプチャグループは便利ですが、必要のない場合に使用すると、メモリと処理時間が無駄になります。キャプチャする必要がない部分には、非キャプチャグループ(?:...)
を使用することで、不要なオーバーヘッドを避けることができます。
// 不要なキャプチャグループ
let regex = /(cat|dog|mouse)/;
// 非キャプチャグループを使用
let optimizedRegex = /(?:cat|dog|mouse)/;
キャプチャが必要ない場合、非キャプチャグループを使うことでパフォーマンスが向上します。
シンプルなパターンの使用
正規表現のパターンは、できるだけシンプルに保つことが重要です。複雑なパターンやネストされたグループは、処理時間が増加する原因となります。可能な限り、単純なパターンで目的を達成するよう心がけましょう。
// 複雑なパターン
let complexRegex = /^(\w+)\s+(\w+)\s+(\w+)$/;
// シンプルなパターン
let simpleRegex = /^\w+\s+\w+\s+\w+$/;
シンプルなパターンを使うことで、パフォーマンスを大幅に改善できることがあります。
短絡評価の活用
|
(オルタネーション)を使用する場合、左側のパターンが一致した場合には右側のパターンが評価されない「短絡評価」が行われます。この特性を活用して、最も頻繁に一致するパターンを左側に配置することで、不要な評価を避け、パフォーマンスを向上させることができます。
let regex = /cat|dog|mouse/; // 頻度に応じて順序を変更
頻繁にマッチするパターンを先に配置することで、正規表現の評価速度を最適化できます。
正規表現のキャッシュ
同じ正規表現を何度も使用する場合、コンパイルされた正規表現オブジェクトをキャッシュすることで、パフォーマンスを向上させることができます。これにより、毎回正規表現を再コンパイルする必要がなくなり、処理時間を削減できます。
let regexCache = {};
function getRegex(pattern) {
if (!regexCache[pattern]) {
regexCache[pattern] = new RegExp(pattern);
}
return regexCache[pattern];
}
let regex = getRegex("cat|dog|mouse");
正規表現のキャッシュを活用することで、頻繁なパターンマッチングを効率的に行うことができます。
バックトラッキングの回避
正規表現のパフォーマンスが大幅に低下する主な原因の一つが「バックトラッキング」です。特に、ネストされた量指定子を使うと、バックトラッキングが過剰に発生することがあります。このような状況を避けるために、量指定子の使い方に注意し、不要なバックトラッキングを防ぐパターンを設計することが重要です。
// バックトラッキングを引き起こす可能性のあるパターン
let regex = /(a+)+/;
// 回避するパターン
let optimizedRegex = /a+/;
バックトラッキングを意識したパターン設計により、正規表現の処理速度が大幅に改善されることがあります。
テストとプロファイリング
正規表現のパフォーマンスを最適化するためには、実際にパターンをテストし、プロファイリングを行ってボトルネックを特定することが重要です。JavaScriptの開発環境には、パフォーマンスを測定するためのツールがいくつか用意されているため、それらを活用して最適化の効果を確認しましょう。
console.time("regexTest");
let regex = /cat/g;
for (let i = 0; i < 10000; i++) {
regex.test("The cat sat on the mat.");
}
console.timeEnd("regexTest");
パフォーマンステストを行うことで、最適化の効果を定量的に評価し、さらに改善点を見つけることができます。
正規表現を使う際には、これらのパフォーマンスの考慮事項を念頭に置いて作業を行うことで、効率的で高速なコードを作成することができます。適切に最適化された正規表現は、アプリケーション全体の性能を向上させる重要な要素となります。
実践演習問題
ここでは、これまでに学んだJavaScriptの正規表現に関する知識を実践的に試すための演習問題を提供します。これらの問題を解くことで、正規表現の理解を深め、実際のシナリオで正規表現をどのように活用するかを学ぶことができます。各問題には、解答例も用意していますので、解いてから答え合わせを行い、理解を確認しましょう。
問題1: 簡単なメールアドレスのバリデーション
以下の要件に基づいて、メールアドレスの形式を確認する正規表現を作成してください。
- メールアドレスは、英数字(a-z, A-Z, 0-9)またはドット(.)、アンダースコア(_)、ハイフン(-)を含むことができます。
@
の前には少なくとも1文字が必要です。@
の後には、ドメイン名があり、ドメイン名の後にはドット(.)で区切られたTLD(トップレベルドメイン)が続きます。- TLDは2文字以上である必要があります。
解答例
let emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(emailRegex.test("user@example.com")); // true
console.log(emailRegex.test("user@example")); // false
問題2: 電話番号のフォーマットチェック
アメリカの電話番号形式(3桁の市外局番、3桁の市内局番、4桁の加入者番号)を確認する正規表現を作成してください。番号は次の形式で表記されます。
123-456-7890
(123) 456-7890
123 456 7890
123.456.7890
解答例
let phoneRegex = /^(\(\d{3}\)\s|\d{3}[-.\s])?\d{3}[-.\s]?\d{4}$/;
console.log(phoneRegex.test("123-456-7890")); // true
console.log(phoneRegex.test("(123) 456-7890")); // true
console.log(phoneRegex.test("123.456.7890")); // true
console.log(phoneRegex.test("123 456 7890")); // true
console.log(phoneRegex.test("123-4567-890")); // false
問題3: HTMLタグの抽出
次のHTML文字列からすべてのタグを抽出する正規表現を作成してください。
<p>This is <em>emphasized</em> text.</p>
解答例
let htmlString = "<p>This is <em>emphasized</em> text.</p>";
let tagRegex = /<[^>]+>/g;
let tags = htmlString.match(tagRegex);
console.log(tags); // ["<p>", "<em>", "</em>", "</p>"]
問題4: 重複する単語の検出
テキスト内で、同じ単語が連続して繰り返されている箇所を見つけ出す正規表現を作成してください。例えば、「This is is a test」のような文から「is is」を検出します。
解答例
let text = "This is is a test.";
let duplicateWordRegex = /\b(\w+)\s+\1\b/g;
let duplicates = text.match(duplicateWordRegex);
console.log(duplicates); // ["is is"]
問題5: 日付フォーマットの変換
YYYY-MM-DD形式の日付文字列を、MM/DD/YYYY形式に変換する正規表現を作成してください。
解答例
let dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
let date = "2024-08-15";
let formattedDate = date.replace(dateRegex, "$2/$3/$1");
console.log(formattedDate); // "08/15/2024"
問題6: クエリパラメータの抽出
次のURLから、すべてのクエリパラメータを抽出してオブジェクトに格納する正規表現とコードを作成してください。
https://example.com/page?param1=value1¶m2=value2
解答例
let url = "https://example.com/page?param1=value1¶m2=value2";
let paramRegex = /[?&]([^=#]+)=([^&#]*)/g;
let params = {};
let match;
while ((match = paramRegex.exec(url)) !== null) {
params[match[1]] = match[2];
}
console.log(params); // { param1: "value1", param2: "value2" }
これらの演習問題を通じて、JavaScriptの正規表現の理解を深め、実際のアプリケーションでどのように使用できるかを体験してください。問題を解くことで、正規表現の力を最大限に引き出すためのスキルが磨かれます。
まとめ
本記事では、JavaScriptのRegExpオブジェクトを使った正規表現の基本から高度なテクニック、そして実践的な応用例までを詳しく解説しました。正規表現は、テキスト操作やデータの検証において非常に強力なツールですが、使い方を誤るとパフォーマンスの問題を引き起こす可能性もあります。記事を通じて、正規表現の基本構文やパターン、フラグの利用、そして高度なテクニックを習得し、効果的に正規表現を活用できるようになったはずです。
また、実践演習問題を通じて、正規表現の実用的な側面を体験し、日常のプログラミング作業でどのように役立つかを確認しました。これらの知識とスキルを活用して、より効率的でメンテナブルなコードを書き、複雑な文字列操作に対応できるようにしていきましょう。
コメント