👻

JavaScript matchの使い所

2024/08/28に公開

🔅Tips

png, jpeg画像ファイルを編集ページで、開くと文字化けしたファイルが表示されてしまう問題があった。HTML, Markdonwといった編集可能なテキストなら、問題なかったので、特定のファイルだけ編集ページで開けるロジックの実装方法を考えた。

連想配列で、APIからデータは取得するので、この中にあるオブジェクトの配列から、画像は除外して、編集ページの閲覧ができるビジネスロジックを考えてみた。

JavaScriptのmatchを使うと実現できた。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match

match() メソッドは、正規表現に対する文字列の照合結果を受け取ります。

const paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';
const regex = /[A-Z]/g;
const found = paragraph.match(regex);

console.log(found);
// Expected output: Array ["T", "I"]

log

> Array ["T", "I"]

ビジネスロジックはこんな感じです。mapでループして、オブジェクトのarrにアクセスして、filtermatchで特定の値を検索して取得する。

let blogs = [
    blog1 = {
        label: 'blog',
        arr: ['hoge.png', 'fuga.jpg', 'hoge.html', 'hoge.md'],
        no:1
    },
    blog2 = {
        label: 'blog',
        arr: ['hoge.png', 'fuga.jpg', 'hoge.html', 'hoge.md'],
        no:2
    },
    blog3 = {
        label: 'blog',
        arr: ['hoge.png', 'fuga.jpg', 'hoge.html', 'hoge.md'],
        no:3
    },
];

// objectの中から、配列を取り出して、その中から、表示したくない画像など特定の拡張子を持つファイルを除外する
// 除外したもの以外は、編集ページで開ける。
const edit = blogs.map((blog) => {
    return blog.arr.filter((item) => {
        return item.match(/\.(html|md)$/);
    });
});

console.log(edit);

if (edit.length > 0) {
    console.log('編集ページで開ける');
}
else {
    console.log('編集ページできない');
}

log

[
  [ 'hoge.html', 'hoge.md' ],
  [ 'hoge.html', 'hoge.md' ],
  [ 'hoge.html', 'hoge.md' ]
]
編集ページで開ける

ポイントは、|を使う。 return item.match(/\.(html|md)$/);htmlか、mdの拡張子のファイルだけ取り出すことができるというものですね。

違うパターンも書いてみた

const blogs = [
    {
        arr: ["file1.html", "file2.md", "image1.jpg", "image2.png"]
    },
    {
        arr: ["file3.html", "file4.md", "image3.gif", "image4.bmp"]
    }
];

// 画像ファイルの拡張子を持つファイルを除外し、ファイル名を表示する
const edit = blogs.map((blog) => {
    const filteredItems = blog.arr.filter((item) => {
        const isImage = item.match(/\.(jpg|jpeg|png|gif|bmp)$/);
        if (isImage) {
            console.log(`画像ファイル: ${item}`);
        }
        return !isImage;
    });
    return filteredItems;
});

console.log(edit);

if (edit.flat().length > 0) {
    console.log('編集ページで開ける');
} else {
    console.log('編集ページできない');
}

log

画像ファイル: image1.jpg
画像ファイル: image2.png
画像ファイル: image3.gif
画像ファイル: image4.bmp
[ [ 'file1.html', 'file2.md' ], [ 'file3.html', 'file4.md' ] ]
編集ページで開ける

reg変数に正規表現は書いた方が良かったかも

const edit = blogs.map((blog) => {
    const filteredItems = blog.arr.filter((item) => {
        const reg = /\.(jpg|jpeg|png|gif|bmp)$/;
        const isImage = item.match(reg);
        if (isImage) {
            console.log(`画像ファイル: ${item}`);
        }
        return !isImage;
    });
    return filteredItems;
});

正規表現のチートシート

基本的なメタ文字

パターン 説明
. 任意の1文字
^ 行の先頭
$ 行の末尾
* 直前の文字が0回以上繰り返される
+ 直前の文字が1回以上繰り返される
? 直前の文字が0回または1回繰り返される
\ エスケープ文字(メタ文字を文字として扱う)

文字クラス

パターン 説明
[abc] abcのいずれか1文字
[^abc] abc以外の任意の1文字
[a-z] 小文字のアルファベット1文字
[A-Z] 大文字のアルファベット1文字
[0-9] 数字1文字
\d 数字1文字([0-9]と同じ)
\D 数字以外の1文字([^0-9]と同じ)
\w 英数字またはアンダースコア1文字([a-zA-Z0-9_]と同じ)
\W 英数字またはアンダースコア以外の1文字([^a-zA-Z0-9_]と同じ)
\s 空白文字(スペース、タブ、改行など)
\S 空白文字以外の1文字

繰り返し

パターン 説明
{n} 直前の文字がちょうどn回繰り返される
{n,} 直前の文字がn回以上繰り返される
{n,m} 直前の文字がn回以上m回以下繰り返される

グループ化と参照

パターン 説明
(abc) abcのグループ
(?:abc) 非キャプチャグループ(後方参照しない)
\1, \2, ... キャプチャグループの後方参照

位置指定子

パターン 説明
\b 単語の境界
\B 単語の境界以外

パターン 説明
^\d{3}-\d{4}$ 郵便番号(例: 123-4567)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ メールアドレス
\b\d{3}-\d{4}\b 文中の郵便番号(例: "住所は123-4567です")

Discussion