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搜索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()));
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
作为旁注,因此,这种行为改变并不是出于任何其他问题的动机:现有的文本编辑者通常不会特别案例,并展示您的原始行为。值得考虑是否需要更改它。