Возможно, этот ответ прибыл немного позже, чем необходимо, но я оставлю его здесь на всякий случай, если кто-то столкнется с той же проблемой сейчас (7 лет, 6 месяцев после того, как этот вопрос был задан).
Теперь взгляды включены в стандарт ECMA2018 и поддерживаются по крайней мере в последней версии Chrome. Однако вы можете решить головоломку с ними или без них.
Решение с отрицательным взглядом:
let testString = `html.htm app.htm foo.tm foo.htm bar.js 1to3.htm _.js _.htm`;
testString.match(/\b(?!foo)[\w-.]+\.htm\b/gi);
> (4) ["html.htm", "app.htm", "1to3.htm", "_.htm"]
Решение с отрицательным взглядом сзади:
testString.match(/\b[\w-.]+(?<!foo)\.htm\b/gi);
> (4) ["html.htm", "app.htm", "1to3.htm", "_.htm"]
Решение с (технически) положительным взглядом:
testString.match(/\b(?=[^f])[\w-.]+\.htm\b/gi);
> (4) ["html.htm", "app.htm", "1to3.htm", "_.htm"]
и т.д.
Все эти регулярные выражения по-разному говорят движку JS об одном и том же: сообщение, которое они передают движку JS, выглядит примерно так:
Пожалуйста, найдите в этой строке все последовательности символов, которые:
- Отдельно от другого текста (как слова);
- Состоит из одной или нескольких букв английского алфавита, подчеркивание (я),
дефис (ы), точка (и) или цифра (ы);
- Конец ".htm";
- Кроме того, часть последовательности перед ".htm" может быть чем угодно
но "фу".