计算实际替代品

问题描述 投票:0回答:1
overview

我创建了一个具有“替换所有”功能的基本文本编辑器。但是,我面临一个问题,即即使文本保持不变,输出表示替换也是如此。这是我的代码的简化版本:

const textarea = document.getElementById('textarea'); const searchInput = document.getElementById('search'); const replaceInput = document.getElementById('replace'); const output = document.getElementById('output'); const replaceButton = document.getElementById('replaceAll'); replaceButton.addEventListener('click', () => { const searchValue = searchInput.value; const replaceValue = replaceInput.value; if (!searchValue) { output.textContent = 'No search term'; return; } const regex = new RegExp(searchValue, 'g'); const matches = textarea.value.match(regex); if (matches) { const count = matches.length; textarea.value = textarea.value.replace(regex, replaceValue); output.textContent = `${count} replacement${count === 1 ? '' : 's'}`; } else { output.textContent = 'No matches'; } });
textarea {
  width: 100%;
  height: 100px;
}

#output {
  color: #666;
}
<textarea id="textarea">apple orange apple orange</textarea>
<input type="text" id="search" placeholder="Search">
<input type="text" id="replace" placeholder="Replace">
<button id="replaceAll">Replace all</button>
<div id="output"></div>

EDGECASE

Non-Regex搜索

text

:苹果橙苹果橙色

    搜索:苹果
  • 替代:苹果
  • 指望输出
  • :“无替代”
  • 电流输出
  • :“ 2替换” Regex搜索
  • text:9/1/2021,3/1/2022
  • search:(\ d*)/\ d*/(\ d {4})
替代:$ 1/1/$2

    指望输出
  • :“无替代”
  • 电流输出
  • :“ 2替换”
  • 问题
  • 如何修改代码以正确处理这些边缘案例,并在替换操作后文本保持不变时显示“无替换”?
  • 执行此操作的一种方法是使用取代函数而不是替换模板:
const replaceAndCount = (str, pattern, replacer) => { let changes = 0; const result = str.replace(pattern, (...args) => { const replacement = replacer(...args); if (replacement !== args[0]) { changes++; } return replacement; }); return {result, changes}; }; console.log(replaceAndCount("hello", /[aeiou]/g, letter => letter.toUpperCase()));

javascript html regex replace
1个回答
0
投票
但是,您必须将替换模板转换为替换功能。例如,这是一个与JavaScript默认值兼容的实现:

const toReplacer = template => { const parts = template.split(/(\$(?:[$&`']|(?!00)(?!0\D)\d{1,2}|<[^>]*>))/); return (...args) => { let string = args.pop(); let groups = undefined; // A final `groups` argument may or may not be present, depending on whether the regex has named groups. if (typeof string === 'object') { groups = string; string = args.pop(); } const index = args.pop(); let result = parts[0]; for (let i = 1; i < parts.length; i += 2) { switch (parts[i].charAt(0)) { case '$': result += '$'; break; case '&': result += args[0]; break; case '`': result += string.substring(0, index); break; case "'": result += string.substring(index + args[0].length); break; case '<': // XXX: for simplicity, not compatible with the default implementation when `groups === undefined` const groupName = parts[i].slice(2, -1); if (groups != null && Object.hasOwn(groups, groupName)) { result += groups[groupName]; } break; default: const groupIndex = parts[i].slice(2, -1); if (Number(groupIndex) < args.length) { result += args[Number(groupIndex)]; } else if (groupIndex.length === 2 && Number(groupIndex.charAt(0)) < args.length) { result += args[Number(groupIndex.charAt(0))] + groupIndex.charAt(1); } else { result += parts[i]; } } result += parts[i + 1]; } return result; }; }; console.log('foo bar baz'.replace(/ba./g, '($&)'));
(如果您在边缘案例中删除严格的兼容性,例如

$12

被解释为

$012

的不同,请根据实际数量数量,您可以将其简化很多。)

作为旁注,因此,这种行为改变并不是出于任何其他问题的动机:现有的文本编辑者通常不会特别案例,并展示您的原始行为。值得考虑是否需要更改它。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.