Заменить часть строки из объекта на возвращаемую переменную или функцию

У меня есть объект, содержащий строку в config.js

exports.message = {
    fromname    : 'admin@bebestorescake.com',
    fromemail   : 'admin@bebestorescake.com', 
    subject     : 'subjek {randomip} {email} {date}', 
    text        : 'Plaintext version of the message',
    letter      : 'your-letter.html',
    list        : 'your-list.txt'
}

В другом файле мне нужно заменить строку {email} {date} {randomip} на некоторую переменную или возвращаемую функцию, как это

{email} replace to email();
{date} replace to date();
{randomip} replace to randomip();

Как это сделать в Node.js

Если вы знаете только, что {randomip}, {email} и {date} находятся где-то в subject, вы можете использовать регулярное выражение для замены этих строк другими строками.

Papi 13.09.2018 21:52

что ты уже испробовал? Ответ есть, но мы не будем этого делать за вас. Мы здесь, чтобы помочь вам, когда вы застряли.

wlh 13.09.2018 21:52

Блин, я слишком много написал? ;)

Papi 13.09.2018 21:54

Я пробовал использовать модуль replace-string, но он просто заменяет одну строку. Я не могу сделать несколько или много строк

mukhlis 13.09.2018 21:54

@MukhlisAkbarrudin с использованием глобального флага в регулярном выражении может помочь вам заменить все экземпляры данной строки или регулярного выражения

oosniss 13.09.2018 21:57
0
5
463
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Для этого вы можете просто связать String#replace():

let exports = {};
exports.message = {
    fromname    : 'admin@bebestorescake.com',
    fromemail   : 'admin@bebestorescake.com', 
    subject     : 'subjek {randomip} {email} {date}', 
    text        : 'Plaintext version of the message',
    letter      : 'your-letter.html',
    list        : 'your-list.txt'
}

exports.message.subject = exports.message.subject
  .replace("{randomip}", randomip())
  .replace("{email}", email())
  .replace("{date}", date());

console.log(exports.message)

// replace this with your own logic
function email(){return "name@domain.tld"}
function randomip(){return "127.0.0.1"}
function date(){return (new Date()).toLocaleString()}

И если вы уверены, что не обрабатываете какой-либо пользовательский ввод, вы также можете использовать eval. Это действительно не зло, просто неправильно поняли:

let exports = {};
exports.message = {
  fromname: 'admin@bebestorescake.com',
  fromemail: 'admin@bebestorescake.com',
  subject: 'subjek {randomip} {email} {date}',
  text: 'Plaintext version of the message',
  letter: 'your-letter.html',
  list: 'your-list.txt'
}

exports.message.subject = exports.message.subject
  .replace(/{([a-zA-Z]+)}/g, function(match) {
    return eval(match.substring(1, match.length - 1) + "()");
  });

console.log(exports.message)

// replace this with your own logic
function email() {return "name@domain.tld"}
function randomip() {return "127.0.0.1"}
function date() {return (new Date()).toLocaleString()}

let exports = {};
exports.message = {
  fromname: 'admin@bebestorescake.com',
  fromemail: 'admin@bebestorescake.com',
  subject: 'subjek {email} {email} {date}',
  text: 'Plaintext version of the message',
  letter: 'your-letter.html',
  list: 'your-list.txt'
}

exports.message.subject = exports.message.subject
  .replace(/{([a-zA-Z]+)}/g, function(match) {
    return eval(match.substring(1, match.length - 1) + "()");
  });

console.log(exports.message)

// replace this with your own logic
function email() {return "name@domain.tld"}
function randomip() {return "127.0.0.1"}
function date() {return (new Date()).toLocaleString()}

привет, братан, а что если в строке есть два тега {e-mail} {e-mail} заменить, это изменит только один, а не все

mukhlis 16.09.2018 12:53

Он вообще не должен заменять e-mail из-за -

Luca Kiebel 16.09.2018 13:11

Я только что проверил, чтобы подтвердить, что {email} {email}делает заменяет оба, если вы нажмете кнопку Show code snippet, вы увидите, что это так.

Luca Kiebel 16.09.2018 14:59

Вы можете использовать шаблонные литералы как быстрое решение:

const replaceTemplate = () => {
  const {email, name} = require('./config.js')
  return `
    ${email} this is an email
    Hello ${name}
  `;
};

Array.prototype.reduce () тоже отлично работает:

const template = 'This is an {email} for {name}';

const obj = {
  email: 'hello@world.com',
  name: 'John Doe'
};
Object.keys(obj).reduce((prev, curr) => prev.replace(`{${obj[curr]}}`), template)

Я бы реализовал это с помощью функции replacer с таблицей отправки:

let { message } = require('config');

function replaceTokens(template) {
  const dispatcher = {
    email: () => 'somestaticaddress@example.com',
    randomip: () => {
      const randomInt = () => Math.floor(Math.random() * 256);
      return `${randomInt()}.${randomInt()}.${randomInt()}.${randomInt()}`;
    },
    date: () => (new Date()).toISOString()
  };
  let output = template;
  template.match(/\{[^}]*\}/g)
    .map(match => match.substring(1, match.length - 1))
    .forEach(token => {
      output = output.replace(new RegExp(`{${token}}`,'g'), dispatcher[token]());
    });
  return output;
}

message.subject = replaceTokens(message.subject);

Приведенное выше заменит экземпляры все токенов в теме.

Вы также можете заменить строку в config.js на функцию:

exports.message = {
    fromname    : 'admin@bebestorescake.com',
    fromemail   : 'admin@bebestorescake.com', 
    subject     : ({randomip, email, date}) => `subjekt ${randomip || ''} ${email || ''} ${date || ''}`, 
    text        : 'Plaintext version of the message',
    letter      : 'your-letter.html',
    list        : 'your-list.txt'
}

А затем при необходимости передайте аргументы:

message.subject({
  email: email(), 
  date: date()
})

Другие вопросы по теме