Возможно ли заменить два вызова replace на один?
Делаю упражнение, и там по идее подразумевается только один вызов replace. У меня получается только двумя. Подскажите пожалуйста, возможно ли всё же сделать это одним.
Вот упражнение:
Imagine you have written a story and used single quotation marks throughout to mark pieces of dialogue. Now you want to replace all the dialogue quotes with double quotes, while keeping the single quotes used in contractions like aren’t.
Think of a pattern that distinguishes these two kinds of quote usage and craft a call to the replace method that does the proper replacement.
Вот мой код:
let text = "'I'm the cook,' he said, 'it's my job.'";
// Change this call.
console.log(text.replace(/(^|[^a-zA-Z])'/g, "$1\"").replace(/'([^a-zA-Z]|$)/g, "\"$1"));
// → "I'm the cook," he said, "it's my job."
Ответы (2 шт):
let text = "'I'm the cook,' he said, 'it's my job.'";
// Change this call.
console.log(text.replace(/\B'/g, "\""));
// → "I'm the cook," he said, "it's my job."
\B - Несловообразующая граница соответствует позиции, в которой предыдущий и следующий символы являются символами одного типа: либо оба должны быть словообразующими символами, либо несловообразующими. Начало и конец строки считаются несловообразующими символами.
Важно: \B не будет работать с кириллицей
UPD: Для символов иных кодировок можно сделать позитивный просмотр назад. В данном случае отрицаем любую букву на латинице или кириллице:
let text = "'I'm the cook,' he said, 'it's my job.'";
console.log(text.replace(/(?<![A-Za-zA-яЁё])'/g, "\""));
let text2 = "'Пример'с кириллицы.'Алфавит, 'Это'ж не с проста.'"
console.log(text2.replace(/(?<![A-Za-zA-яЁё])'/g, "\""));
Но и это не совсем законченный вариант, раз вопрос был не в решении конетретного примера, то стоит учесть, что будет пропущен знак припенания, тогда нам нужно будет условие иначе в регулярном выражении.
const reg = /((?<![A-Za-zA-яЁё])'|'(?![A-Za-zA-яЁё]))/g
let text = "'I'm the cook' he said, 'it's my job'";
let text2 = "'Пример'с без точки в конце' Тест 'Это'ж не с проста'";
console.log(text.replace(reg, "\""));
console.log(text2.replace(reg, "\""));
Границы слова, поддерживающие Юникод:
(?<!\p{Alphabetic}\p{M}*)- левая граница слова (блок предварительного просмотора назад, отменяющий совпадение, если сразу перед текушей позицией есть любой алфавитный символ + ноль и более диакритических знаков)(?!\p{Alphabetic})- правая граница слова (блок предварительного просмотора вперёд, отменяющий совпадение, если сразу после текушей позиции есть любой алфавитный символ).
Решение, которое поддреживает все буквы Юникода:
const regex = /(?<!\p{Alphabetic}\p{M}*)'|'(?!\p{Alphabetic})/gu;
let text = "'I'm the cook' he said, 'it's my job'\n'Пример'с без точки в конце' Тест 'Это'ж не с проста'\n'Eł'z, ńóść'";
console.log(text.replace(regex, '"'));
Регулярное выражение тут
/(?<!\p{Alphabetic}\p{M}*)'|'(?!\p{Alphabetic})/gu
См. пример работы.