JavaScriptの正規表現でURLなどの文字列の間の文字列を検出/取得する方法

自分の写真結城永人 -

正規表現で文字列の間、一つの部分から他の部分までを指定するには両端を任意で決めて中間をパターンで記載する。

何でも良ければ「.*」(どんな文字でもなければなくてあればあるだけ続く:文字の0以上の繰り返しという指定)が一般的に使える。

例えばサイトや画像などのURLで半角スラッシュ(/)の間を指定するには「/.*/」のように記載する。

参考:正規表現パターンの記述

JavaScriptで使う場合は文字列の半角スラッシュはエスケープしなくてはならないので、正規表現リテラル(/文字列/)ならば半角バックスラッシュを前に一つ追加して「\/.*\/」、それを正規表現オブジェクト(RegExp()コンストラクター)に渡すならば半角バックスラッシュを前に二つ追加して「\\/.*\\/」と書き換えることになる。

イスタンブールの多くの建物が密集した景色

test()メソッドの正規表現の文字列の検出

JavaScriptのtest()メソッドは正規表現を使って一つの文字列が他の文字列に含まれるかどうかの有無を検出することができる。

正規表現.test(引数)

正規表現リテラルか正規表現オブジェクトを指定して引数にそれが含まれるかどうかを検出したい文字列を入れる。

URLの一部の文字列の有無を検出するサンプル

URLの「https://www.nagahitoyuki.com/2020/01/」がある。

検出:半角スラッシュの間に「URL」は含まれるか。

検出:半角スラッシュの間に「com」は含まれるか。

HTML

<div id="regexp1">
  <p>URLの「https://www.nagahitoyuki.com/2020/01/」がある。</p>
  <p>検出:半角スラッシュの間に「URL」は含まれるか。</p>
  <p>検出:半角スラッシュの間に「com」は含まれるか。</p></div>
<button id="run1" type="button">実行/button>
<button id="reset1" type="button" disabled="true">再開</button>

JavaScript

const obj1 = regexp1.querySelectorAll("p"), tcu1 = obj1[0].textContent, chtc1 = obj1[1].textContent, chtc2 = obj1[2].textContent;
run1.addEventListener("click", () => {
obj1[1].textContent = /\/.*URL.*\//.test(tcu1) ? chtc1.replace("含まれるか", "含まれる\uff08true\uff09") : chtc1.replace("含まれるか", "含まれない\uff08false\uff09");
obj1[2].textContent = /\/.*com.*\//.test(tcu1) ? chtc2.replace("含まれるか", "含まれる\uff08true\uff09") : chtc2.replace("含まれるか", "含まれない\uff08false\uff09");
run1.disabled = true; reset1.disabled = false; });
reset1.addEventListener("click", () => {
obj1[1].textContent = chtc1; obj1[2].textContent = chtc2; run1.disabled = false; reset1.disabled = true; });

test()メソッドで二つの半角スラッシュのどれか、文字列に、二つ以上、あれば最も外側の半角スラッシュに正規表現で指定する文字列があるかどうかの有無を検出した。

正規表現の部分はJavaScriptのエスケープを除くと「/.*URLかcom.*/」となっていて両端の半角スラッシュとその間の文字列がさらにその間に「.*」で他の何かの文字を挟まないか幾つ挟んでも構わないというふうに捉えている。

すると最も外側の半角スラッシュの間に確定した文字列の「URL」か「com」があればtrue(真)、なければfalse(偽)の検出結果を得られるわけなんだ。

検出される文字列の途中の半角スラッシュの間を対象とするならば正規表現のパターンを変えて対応する。

例えば三番目と四番目の半角スラッシュの間の文字列を検出するならば「/.*/.*/.*文字列.*/」のように前に半角スラッシュを含めた指定を増やすなどの方法がある。

正規表現の指定を増やせば文字列の有無を絞り込んで狭く、減らせば広く検出することができる。

参考:RegExp.prototype.test()

exec()メソッドの正規表現の文字列の取得

JavaScriptのexec()メソッドは正規表現を使って一つの文字列が他の文字列に含まれる場合にその部分を配列で取得することができる。

正規表現.exec(引数)

正規表現リテラルか正規表現オブジェクトを指定して引数にそれが含まれる部分を取得したい文字列を入れる。

URLの一部の文字列を幾つか取得するサンプル

URLの「https://www.nagahitoyuki.com/2020/01/」がある。

半角スラッシュで囲まれた部分の文字列の取得

    HTML

    <div id="regexp2">
      <p>URLの「https://www.nagahitoyuki.com/2020/01/」がある。</p>
      <p>半角スラッシュで囲まれた部分の文字列の取得</p>
      <ul style="height:4.8em;"></ul></div>
    <button id="run2" type="button">実行</button>
    <button id="reset2" type="button" disabled="true">再開</button>

    JavaScript

    const obj2 = regexp2.querySelectorAll("*"), tcu2 = obj2[0].textContent, gtul = obj2[2], relr = /\/([^\/]+)\//g;
    run2.addEventListener("click", () => {
    let ary = [];
    while ((ary = relr.exec(tcu2)) !== null) {
    const upl = document.createElement("li");
    upl.textContent = ary[1]; gtul.appendChild(upl); relr.lastIndex -= 1; }
    run2.disabled = true; reset2.disabled = false; });
    reset2.addEventListener("click", () => {
    gtul.textContent = ""; run2.disabled = false; reset2.disabled = true; });

    exec()メソッドで二つの半角スラッシュの間の文字列を正規表現で指定して全て取得した。

    正規表現のパターンはJavaScriptのエスケープを除くと「/([^/]+)/」で、両端に半角スラッシュがあり、その間に半角スラッシュを除外した文字集合([^/])を一つ以上の連続(+)で指定して二つの半角スラッシュの間(内側に半角スラッシュを挟まない部分)の文字列を検索対象としている。

    exec()メソッドは半角括弧(())で囲った部分のキャプチャグループを個別に取得できるから二つの半角スラッシュの間の文字列の「[^/]+」を半角括弧で囲んで「([^/]+)」と記載している。

    半角括弧を使わないと正規表現が指定する全体として両端の半角スラッシュも含めて取得される。

    exec()メソッドは普通に使うと検索対象の文字列の最初の一つしか取得できない。

    複数を取得する場合はサンプルのようにwhile文などで繰り返しの処理を行う。

    検索する毎に正規表現に見付けた文字列の位置のlastIndexが追加されるので、繰り返しの処理では次にそこから検索して前のものを除外することになる、文字列の最後まで行って検索対象がなくなると「null」を返すからそこまで繰り返しの処理を行えば全ての検索対象を取得することができる。

    文字列の全体を検索対象とするために正規表現の右端に「/g」とgフラグを付ける。正規表現にgフラグなしでexec()メソッドの繰り返しを行うと止まらなくなるから注意しなくてはならない。

    サンプルでは半角スラッシュを一つずつ追跡するために「relr.lastIndex -= 1」と正規表現のlastIndexを繰り返し毎に一つ引いて使っている。何もしないと次の検索で、次の半角スラッシュまでの文字列が無視される(前の半角スラッシュの直後から検索が始った部分は左側に半角スラッシュがないものと見做されるため)。一つ戻しておくと改めて正規表現でて指定された検索対象に含めることができる。

    取得される文字列は配列で、内容は0が全体で、もしも半角括弧で囲まれたキャプチャグループの文字列があれば1以降に順番に格納される。

    なので文字列の全体的な構成から部分の文字列をキャプチャグループで一つずつ捉えることもできる。

    例えばURLを「^.*//(.*)/(.*)/(.*)/$」(^は先頭、$は末尾の指定)とした場合、exec()メソッドでは半角スラッシュで囲まれた半角括弧内の三つの文字列が順番に添字の[1]と[2]と[3]で取り出せる。

    部分の文字列が同じパターンで幾つもあっても必要なものの順番が定まっているならば文字列の全体的な構成からキャプチャグループを使って添字で取得するのが簡単だろう。

    参考:RegExp.prototype.exec()

    コメント