2014-07-24 4 views
2

Я пытаюсь сопоставить все привязки на странице, ссылающейся на файлы с определенными расширениями, но код также захватывает случаи, когда URL-адрес заканчивается текстом расширения, но не содержит фактическое расширение (без периода).Соответствие регулярному выражению JavaScript игнорирует литеральную точку

Например, он должен (и делает) соответствовать http://example.com/image.jpg, но это также соответствует http://example.com/imagejpg (что я не хочу).

Код используется:

var imageExtensions = "jpg|jpeg|gif|png|svg"; 

var allAnchors = document.getElementsByTagName("a"); 
for(var i = 0; i < allAnchors.length; i++) { 
    var anchorWithImage = allAnchors[i]; 

    var matcher = new RegExp(".*\.(" + imageExtensions + ")$"); 
    if(matcher.test(anchorWithImage.href)) { 
     alert(anchorWithImage.href); 
    } 
} 

Я нахожусь под впечатлением, что это должно требовать, чтобы текст расширения находится в конце строки, буквальный период перед расширением, и может быть ничего перед расширением. Я не понимаю, почему буквальный период игнорируется.

Для реальных данных теста я запускал этот скрипт с http://www.reddit.com/r/gifs/comments/2bis0x/holy_shit_greg/, и он соответствует http://www.reddit.com/r/makemeagif, который не имеет буквального периода. Ожидаемые результаты для этих ссылок против this Regex tester.

ответ

2

Как вы используете конструктор RegExp, вы передаете строку для создания регулярного выражения. Ваша обратная косая черта, чтобы избежать точки в выражении, есть в качестве спуска в строке. Решение состоит в том, чтобы избежать точку с обратной косой черты: двойной

var matcher = new RegExp(".*\\.(" + imageExtensions + ")$"); 

Теперь слэш экранируется в строке, позволяя ему сделать это через анализатор в конструктор RegExp, чтобы избежать точки.

+1

Это действительно проблема. Хороший улов. Слэш должен быть экранирован. Я неправильно предполагал, что недействительные escape-последовательности (например, '\ .') будут рассматриваться как буквальные. – Kat

0

Другой вариант кода :)

var a = document.getElementsByTagName("A"); 
var pattern = /^(http:\/\/)?(.*)\.(jpg|jpeg|png|gif|svg)$/gi; 

for(var i = 0; i < a.length; i++){ 
    if(a[i].href.match(pattern)) 
     alert(a[i].href); 
} 
+0

Хотя этот не будет работать с локальными файлами, что является немного искусственным ограничением. Кроме того, я хотел бы извлечь список расширений в свою собственную строку, так как я планирую настроить ее позже. – Kat

+0

@Mike Я обновил фрагмент выше, чтобы он соответствовал локальным файлам :) – hex494D49

Смежные вопросы