As I've mentioned, maybe GAS is the only way to go here. But as
@Rubén mentioned, they can't be custom.
So my solution is run a function, which I called "checker", via a drawing or a menu. The function called "reset" is just there as a quick way to delete the list of names.
The biggest advantage with this approach is that the external file is called just once! I've even made it display (in C2) the external file's last modified date so the users will know if the match is based on current data or not.
The Spreadsheet structure is:
A B C
1 ID/Name https://... =REGEXEXTRACT(B1, "d/(.+)/") or just filename.txt
2 Charset UTF-8
3
4 Name Match
5 Joe Smith =...
6 Jane Smith =...
7 Foo Bar =...
(Cell B1 is either a link like https://drive.google.com/file/d/1234abcd/view or a file name - my function will take the first file with that name)
function reset() {
var spreadsheet = SpreadsheetApp.getActiveSheet(), firstrow = 4;
spreadsheet.getRangeList(["a" + firstrow + ":b", "c2"]).clearContent();
}
function checker() {
var regex = '^{value}$', regex_mod = 'mi', file, found, name = '.', id, value, charset, spreadsheet = SpreadsheetApp.getActiveSheet(), popup = SpreadsheetApp.getUi(), i, firstrow = 4, maxrows;
spreadsheet.getRange("b" + firstrow + ":b").clear;
maxrows = spreadsheet.getMaxRows();
id = spreadsheet.getRange('c1').getValue();
charset = spreadsheet.getRange('b2').getValue();
if (id.indexOf(name) == -1)
file = DriveApp.getFileById(id);
else
file = DriveApp.getFilesByName(id).next();
spreadsheet.getRange("c2").setValue(file.getLastUpdated());
if (charset == null)
file = file.getBlob().getDataAsString();
else
file = file.getBlob().getDataAsString(charset);
for (i=firstrow; i<=maxrows; i++) {
value = spreadsheet.getRange(i, 1).getValue();
if (value == '')
break;
value = new RegExp(regex.replace('{value}', preg_quote(value, '')), regex_mod);
spreadsheet.getRange(i, 2).setValue(value.test(file));
}
}
function preg_quote (str, delimiter) { // eslint-disable-line camelcase
// discuss at: http://locutus.io/php/preg_quote/
// original by: booeyOH
// improved by: Ates Goral (http://magnetiq.com)
// improved by: Kevin van Zonneveld (http://kvz.io)
// improved by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// example 1: preg_quote("$40")
// returns 1: '\\$40'
// example 2: preg_quote("*RRRING* Hello?")
// returns 2: '\\*RRRING\\* Hello\\?'
// example 3: preg_quote("\\.+*?[^]$(){}=!<>|:")
// returns 3: '\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:'
return (str + '')
.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&')
}