Множественная замена , нескольких подстрок в строке, на разные заменяемые значения String.replace js javaScript
Всем доброго времени суток, нужна помощь в решении не большой задачи:
Нужно в строке , заменить несколько подстрок, разными значениями , первая подстрока на значение переменной , а вторая подстрока на строку но в виде таблицы html с данными из масива.
Пример :
let ageAndrew = '14';
let text = 'Меня зовут Андрей, мой возраст ageAndrew , все данные о моей семье: table';
Где собственно ageAndrew это первая подстрока которую надо заменить , а table вторая.
Есть массив со всеми данными о родных Андрея.
let people = [
{
'name' : 'Александр',
'surName' : 'Андреев',
'age' : '33',
'dateOfBirth' : '02031990'
},
{
'name' : 'Нина',
'surName' : 'Андреева',
'age' : '31',
'dateOfBirth' : '05051992'
},
{
'name' : 'Андрей',
'surName' : 'Андреев',
'age' : '14',
'dateOfBirth' : '05052009'
}
]
сделал собственно таблицу в HTML для представления, как это должно быть внутри строки:
<label>Данные о моей семье</label>
<table>
<tr>
<td>Имя</td>
<td>Фамилия</td>
<td>Возраст</td>
<td>Дата рождения</td>
</tr>
<tbody>
<tr ng-repeat="row in people">
<td ng-bind="row.name"></td>
<td ng-bind="row.surName"></td>
<td ng-bind="row.age"></td>
<td ng-bind="row.dateOfBirth"></td>
</tr>
</tbody>
</table>
И вот тут самое интересное, я хочу заменить в тексте ageAndrew на 14, а вместо table вставить отрисованную таблицу как в html, чтоб было видно в браузере как таблицу, но заменять я планирую её как строку ( как я это понимаю ).
Думаю для этого стоит использовать String.replace(), если я делаю 1 замену в строке , то есть заменяю 1 подстроку, то всё ок, вот например:
let newStr = text.replace(/ageAndrew/,ageAndrew);
а вот как заменить сразу 2 подстроки , разными значениям (переменными) не совсем понимаю,
возможно нужно использовать рег. выражения , но я в них плох.
Буду благодарен за любой совет или пример как решить задачу.
И вот как быть с таблицей в виде строки, возможно ли такое сделать? В гуглинге чёт ничего такого не нашёл.
Ответы (2 шт):
Если нужно именно заменить, то меняйте сначала одно, а следом другое. В чём проблема два раза применить replace ? Чтобы отображалась форматированная таблица - вставляйте строку, как HTML.
let text = "Меня зовут Андрей, мой возраст ageAndrew, все данные о моей семье: table";
let ageAndrew = "14";
let people = [
{ name: "Александр", surName: "Андреев", age: "33", dateOfBirth: "02031990" },
{ name: "Нина", surName: "Андреева", age: "31", dateOfBirth: "05051992" },
{ name: "Андрей", surName: "Андреев", age: "14", dateOfBirth: "05052009" }
];
let table = document.createElement('table');
table.innerHTML = `<tr><th>Имя</th><th>Фамилия</th><th>Возраст</th><th>Дата рождения</th></tr>`;
people.forEach((row) => {
table.tBodies[0].insertAdjacentHTML(
"beforeend",
`<tr ng-repeat="row in people">
<td ng-bind="${row.name}">${row.name}</td>
<td ng-bind="${row.surName}">${row.surName}</td>
<td ng-bind="${row.age}">${row.age}</td>
<td ng-bind="${row.dateOfBirth}">${row.dateOfBirth}</td>
</tr>`
);
});
let newStr = text.replace(/ageAndrew/, ageAndrew).replace(/table/, table.outerHTML);
document.body.insertAdjacentHTML("beforeend", newStr);
Здесь очень упрощённое решение. Но, во-первых, так нагляднее. А, во-вторых, для вставки строкой, это не так критично.
Имя и возраст
Для того чтобы одновременно произвести замену нужно вместо строки замены подставить функцию, в документации она называется replacer, не забывайте обращаться к документации, там много полезного и примеры есть.
Что касается имени нашего героя Андрея и его возраста, то замена происходит на основе регулярки. Чтобы не делать ее слишком сложной я сделал ее проще (такую регулярку можно сгенерировать через код).
/(personName)|(personAge)/g
Мы вставляем строки из шаблона в группы которые представлены скобками и делаем разделитель | который обозначает или таким образом мы ищем или то или это, а флаг g обозначает глобальный поиск без него поиск и замена произойдет только с первым совпадением а остальные так и остануться как были.
Пример генерации такой регулярки из объекта:
const personData = {personName: 'Andrew', personAge: 14}
const reg = new RegExp(Object.keys(personData).map(key =>`(${key})`).join('|'), 'g')
console.log(reg)
Еще один более простой способ множественной замены — использовать шаблонную строку:
const p = {personName: 'Andrew', personAge: 14}
console.log(`Меня зовут ${p.personName}, мой возраст ${p.personAge}`)
Таблица
Не совсем понимаю зачем Вам в строку вставлять таблицу, но по аналогии с данными героя можете вставить и ее.
Я так понял Вы пишите на Angular, думаю у Вас и так все с таблицей хорошо через ng-repeat в принципе и в заменяемую первую строку текста можно было вклинить данные, не совсем понятно зачем Вам использовать replace. Мне кажется использовать данные из модели гораздо проще и правильнее для Angular
<p>Меня зовут {{person.name}}, мой возраст {{person.age}}</p>
Хотя я на нем давно не писал ничего. У него есть хорошие примеры возможно, Вы не знали, поэтому на всякий случай добавил в ответ.
Я не использовал тех аттрибутов которые у Вас, продемонстировал на простом HTML. Для таблицы я применил innerHTML в некоторых случаях это не безопасно, поэтому лучше так не делать, либо проверять что данные которые вставляются только из букв и цифр. А лучше использовать textContent или innerText Я проверку такую не делал, но на основе регулярок Вы легко можете ее сделать сами, заодно научитесь их использовать.
const person = document.getElementById('person');
const family = document.querySelector('table#family > tbody');
function makeInfo(personData, familyData){
const template = 'Меня зовут personName, мой возраст personAge';
person.textContent = template.replace(/(personName)|(personAge)/g,
function(match){
return personData[match] // ключ берем из совпадения, данные из personData
})
tableRows= familyData.map(({name, surName, age, dateOfBirth})=> (
`<tr>
<td>${name}</td>
<td>${surName}</td>
<td>${age}</td>
<td>${dateOfBirth}</td>
</tr>`
)).join('');
family.innerHTML = tableRows
}
const familyData = [
{
'name' : 'Александр',
'surName' : 'Андреев',
'age' : '33',
'dateOfBirth' : '02031990'
},
{
'name' : 'Нина',
'surName' : 'Андреева',
'age' : '31',
'dateOfBirth' : '05051992'
},
{
'name' : 'Андрей',
'surName' : 'Андреев',
'age' : '14',
'dateOfBirth' : '05052009'
}
]
const personData = {personName: 'Andrew', personAge: 14}
makeInfo(personData, familyData)
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<p id="person">123</p>
<label>Данные о моей семье:</label>
<table id="family" border="1">
<thead>
<tr>
<tr>
<td>Имя</td>
<td>Фамилия</td>
<td>Возраст</td>
<td>Дата рождения</td>
</tr>
</tr>
</thead>
<tbody></tbody>
</table>
Для качества кода старайтесь давать более точные имена переменным, программисты это ценят. Надеюсь мои объяснения, код и рекомендации окажуться полезными.