はじめに
GAS(Google Apps Script)でスプレッドシート検索やWebアプリの検索フォームを作ると、同じ値なのに検索にヒットしないことがあります。
よくある原因は、ユーザー入力と保存データの表記揺れです。
ABCとabcABCとABC123と123Item-01とItem-01
この違いを毎回個別に判定すると、検索処理が複雑になります。そこで、検索する前に文字列を同じ形へそろえる正規化関数を用意しておきます。
この記事では、GASで使いやすい normalize_ 関数と、スプレッドシート検索へ組み込む実装例を紹介します。
この記事で解決できること
- GASの検索で全角英数字と半角英数字を同じものとして扱う
- 大文字と小文字を無視して検索する
- スプレッドシートの一覧検索で表記揺れによる検索漏れを減らす
String.prototype.normalize('NFKC')に頼らず、GASで安定して動く変換を用意する
結論:検索前に両方の文字列を正規化する
ポイントは、検索キーワードだけでなく、検索対象のデータも同じ関数に通すことです。
var normalizedQuery = normalize_(userInput);
var normalizedTarget = normalize_(dataValue);
if (normalizedTarget.indexOf(normalizedQuery) !== -1) {
// ヒット
}
片方だけ正規化しても、比較対象の形がそろわないため検索漏れが残ります。
こんな場面で使えます
- スプレッドシートのデータを検索・フィルタリングするWebアプリ
- 商品コード、社員番号、案件番号など英数字を含む値の検索
- ユーザーが全角英数字で入力しても検索できるフォーム
ABC、abc、ABCをすべて同じものとして扱いたい処理
実装コード
正規化関数
以下の関数を追加すると、全角英数字を半角英数字へ変換し、英字を小文字に統一できます。
/**
* 検索比較用に文字列を正規化する。
* - null / undefined を空文字として扱う
* - 前後の空白を削除
* - 英字を小文字へ統一
* - 全角英数字を半角英数字へ変換
*/
function normalize_(value) {
return String(value == null ? '' : value)
.trim()
.toLowerCase()
.replace(/[A-Za-z0-9]/g, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
}
この関数では、検索で扱いやすいように null や undefined も空文字として処理しています。スプレッドシートの空セルを検索対象に含めても、エラーで止まりにくくなります。
仕組み
処理の流れはシンプルです。
String(value == null ? '' : value)で値を文字列化trim()で前後の空白を削除toLowerCase()で大文字と小文字を統一- 正規表現
/[A-Za-z0-9]/gで全角英数字だけを検出 - Unicodeコードポイントから
0xFEE0を引いて半角へ変換
0xFEE0 は、全角英数字と半角英数字のUnicodeコードポイントの差分です。たとえば A(U+FF21)から 0xFEE0 を引くと A(U+0041)になります。
スプレッドシート検索に組み込む例
以下は、A列の名前を検索する例です。
function searchData(keyword) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('データ');
var data = sheet.getDataRange().getValues();
var normalizedKeyword = normalize_(keyword);
var results = [];
for (var i = 1; i < data.length; i++) {
var name = normalize_(data[i][0]);
if (name.indexOf(normalizedKeyword) !== -1) {
results.push(data[i]);
}
}
return results;
}
この形にしておくと、シート側に ABC株式会社 と入っていても、ユーザーが abc と検索したときにヒットします。
複数列をまとめて検索する例
業務アプリでは、会社名、担当者名、管理番号など複数列をまとめて検索したいことも多いです。その場合は、検索対象の列を連結してから正規化します。
function searchRows(keyword) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('データ');
var values = sheet.getDataRange().getValues();
var query = normalize_(keyword);
var results = [];
for (var i = 1; i < values.length; i++) {
var row = values[i];
var target = normalize_([
row[0], // 会社名
row[1], // 担当者名
row[2], // 管理番号
].join(' '));
if (target.indexOf(query) !== -1) {
results.push(row);
}
}
return results;
}
検索対象を1つの文字列にまとめておくと、列ごとに if を増やさずに済みます。
カタカナの全角・半角も統一したい場合
この関数は、英数字の全角/半角変換に絞っています。
半角カタカナの ガ と全角カタカナの ガ のような変換まで扱う場合は、濁点・半濁点の結合も考える必要があり、英数字より複雑です。
ブラウザ側だけで処理できる場合は normalize('NFKC') が候補になります。ただし、GASのサーバー側で安定して動かしたい場合は、必要な文字だけ変換テーブルを用意するほうが安全です。
注意点・ハマりポイント
- 表示用データまで正規化しないようにします。正規化は検索比較用に限定するのが安全です。
- 商品コードなどで大文字と小文字を区別したい場合、この関数は使わないでください。
- 記号の全角/半角、ひらがな/カタカナ、濁点付きカタカナまで扱う場合は、要件を分けて追加実装します。
- データ件数が多い場合は、毎回全行を正規化すると遅くなります。検索用の正規化済み列を別途持つ設計も検討してください。
実務での使いどころ
GASの業務アプリでは、入力する人によって全角英数字、半角英数字、大文字、小文字が混ざることがよくあります。
検索処理の入口に normalize_ を置いておくと、表記揺れによる「あるはずのデータが見つからない」という問い合わせを減らせます。
特に、スプレッドシートを簡易データベースとして使うWebアプリでは、早い段階で検索用の正規化ルールを決めておくと後から楽になります。
関連記事
まとめ
- GASの検索では、全角半角・大文字小文字の違いで検索漏れが起きやすい
normalize_関数で検索キーワードと検索対象の両方を正規化する- 英数字だけなら、Unicodeコードポイントの差分を使ってシンプルに変換できる
- 表示用データは変えず、検索比較用の文字列だけを正規化する
