2010-06-16 2 views
14

У меня есть массив с:Заменить список смайликов с их изображениями

emoticons = { 
    ':-)' : 'smile1.gif', 
    ':)' : 'smile2.gif', 
    ':D' : 'smile3.gif'  
} 

тогда у меня есть variabile с текстом.

var text = 'this is a simple test :)'; 

и переменная с URL сайта

var url = "http://www.domain.com/"; 

Как написать функцию, которая заменяет символы с их образами?

Результат <img> тег должен быть:

<img src="http://www.domain.com/simple2.gif" /> 

(я должен конкатенации URL-адрес varible на имя образа).

Отклонитесь!

ответ

4
for (smile in emoticons) 
{ 
    text = text.replace(smile, '<img src="' + url + emoticons[smile] + '" />'); 
} 
+1

Это не сработает правильно, поскольку замена заменяет только первое вхождение совпадающей строки. – Matias

+0

Работает только для замены первого появления каждого смайлика. В строке типа «Это заменено :), но не это :)», второй остается неизменным. – Guffa

+1

Также не забудьте использовать 'var' в' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ', если код находится внутри функции, 'if (emoticons.hasOwnProperty (улыбка))' внутри цикла - хорошая идея. – CMS

33

Другой подход:

function replaceEmoticons(text) { 
    var emoticons = { 
    ':-)' : 'smile1.gif', 
    ':)' : 'smile2.gif', 
    ':D' : 'smile3.gif' 
    }, url = "http://www.domain.com/"; 
    // a simple regex to match the characters used in the emoticons 
    return text.replace(/[:\-)D]+/g, function (match) { 
    return typeof emoticons[match] != 'undefined' ? 
      '<img src="'+url+emoticons[match]+'"/>' : 
      match; 
    }); 
} 

replaceEmoticons('this is a simple test :)'); 
// "this is a simple test <img src="http://www.domain.com/smile2.gif"/>" 

Edit:@pepkin88 сделал очень хорошее предложение, построить регулярное выражение, основанное на именах свойств в emoticons объекта.

Это легко сделать, но мы должны избегать метасимволов, если хотим, чтобы это работало правильно.

Экранированные шаблоны хранятся в массиве, который затем используется для построения регулярного выражения с использованием конструктора RegExp, в основном, соединяющего все шаблоны, разделенные метасимволом |.

function replaceEmoticons(text) { 
    var emoticons = { 
    ':-)' : 'smile1.gif', 
    ':)' : 'smile2.gif', 
    ':D' : 'smile3.gif', 
    ':-|' : 'smile4.gif' 
    }, url = "http://www.domain.com/", patterns = [], 
    metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g; 

    // build a regex pattern for each defined property 
    for (var i in emoticons) { 
    if (emoticons.hasOwnProperty(i)){ // escape metacharacters 
     patterns.push('('+i.replace(metachars, "\\$&")+')'); 
    } 
    } 

    // build the regular expression and replace 
    return text.replace(new RegExp(patterns.join('|'),'g'), function (match) { 
    return typeof emoticons[match] != 'undefined' ? 
      '<img src="'+url+emoticons[match]+'"/>' : 
      match; 
    }); 
} 

replaceEmoticons('this is a simple test :-) :-| :D :)'); 
+1

Было бы еще лучше, если бы регулярное выражение создавалось в зависимости от значений ключей в' emoticons'. – pepkin88

+1

@ pepkin88: Отличное предложение :), я добавил функцию, которая делает это возможным. – CMS

+1

Это может быть дополнительно усилено закрытием 'replace()' (похоже на [этот ответ] (http://stackoverflow.com/questions/286921/javascript-efficiently-replace-all-accented-characters-in-a -string/614397 # 614397) ...) - это ускорит повторные вызовы функции. – Tomalak

0

Использование регулярного выражения с множеством элементов для замены элементов поиска хорошо работает.

var emotes = [ 
    [':\\\)', 'happy.png'], 
    [':\\\(', 'sad.png'] 
]; 

function applyEmotesFormat(body){ 
    for(var i = 0; i < emotes.length; i++){ 
     body = body.replace(new RegExp(emotes[i][0], 'gi'), '<img src="emotes/' + emotes[i][1] + '">'); 
    } 
    return body; 
}