我有一段代码,其目标是用锚标记替换@something的每一个出现。替换本身工作正常,循环通常不会。只需要考虑这是一个字符串操作方法,它必须找到某些东西,然后用其他东西替换它 - 但不能替换所有,因为它取决于'@'字符后面的内容。
这是代码。
private generateAnchors(content: string) {
let cutIndex = 0;
let contentToReturn = content;
let leftToAnalyze = content;
if (leftToAnalyze.indexOf('@') !== -1) {
while (true) {
leftToAnalyze = content.substring(cutIndex);
leftToAnalyze = leftToAnalyze.substring(content.indexOf('@'));
let tag = leftToAnalyze.substring(leftToAnalyze.indexOf('@'), leftToAnalyze.indexOf(' ', leftToAnalyze.indexOf('@')));
cutIndex += leftToAnalyze.indexOf(tag)+tag.length;
let address = tag.substring(1, tag.length);
let anchor = '<a href="/home/user/'+address+'">'+tag+'</a>';
let newContentSubString = leftToAnalyze.replace(tag, anchor);
contentToReturn = contentToReturn.replace(leftToAnalyze, newContentSubString);
if (leftToAnalyze.indexOf('@') === -1) break;
}
}
return contentToReturn;
}
在一个小字符串中,如'hello @JEDS&amp; @Mill还@theHulk值得一提' 它工作正常。但是我发现有一个更大的字符串出现,其中@标签位于字符串的末尾,它看起来像是永远循环,并且替换它也不应该是它。
我在这段代码中监督什么?
答案 0 :(得分:1)
您的cutIndex
计算中存在错误。它在tag
中查找leftToAnalyze
的索引,并在循环开始时将该索引用于content
(即leftToAnalyze = content.substring(cutIndex)
),使其分析相同的文本从上一次运行开始。
cutIndex
实际上应该在查看content
:
// cutIndex += leftToAnalyze.indexOf(tag)+tag.length; // DON'T DO THIS
cutIndex += content.indexOf(tag)+tag.length;
此外,如果leftToAnalyze
为空,循环应该提前保释:
while (true) {
leftToAnalyze = content.substring(cutIndex);
const indexOfFirstAt = content.indexOf('@');
leftToAnalyze = leftToAnalyze.substring(indexOfFirstAt);
// nothing left? bail
if (!leftToAnalyze) break;
...
}
function generateAnchors(content) {
let cutIndex = 0;
let contentToReturn = content;
let leftToAnalyze = content;
if (leftToAnalyze.indexOf('@') !== -1) {
let limit = 100;
let i = 0;
while (i++ < limit) {
leftToAnalyze = content.substring(cutIndex);
const indexOfFirstAt = content.indexOf('@');
leftToAnalyze = leftToAnalyze.substring(indexOfFirstAt);
if (!leftToAnalyze) break;
const indexOfNextAt = leftToAnalyze.indexOf('@');
const indexOfSpace = leftToAnalyze.indexOf(' ', indexOfNextAt);
let tag = leftToAnalyze.substring(leftToAnalyze.indexOf('@'), indexOfSpace);
cutIndex += content.indexOf(tag)+tag.length;
let address = tag.substring(1, tag.length);
let anchor = '<a href="/home/user/'+address+'">'+tag+'</a>';
let newContentSubString = leftToAnalyze.replace(tag, anchor);
contentToReturn = contentToReturn.replace(leftToAnalyze, newContentSubString);
if (leftToAnalyze.indexOf('@') === -1) break;
}
}
return contentToReturn;
}
const input = 'foo @bar baz @qux @ @@@@@';
const output = generateAnchors(input);
console.log(output);
但我建议使用正则表达式简化代码。实际上,这个循环可以简化为一行String#replace
:
return content.replace(/(@([^ @]+))/ig, '<a href="/home/user/$2">$1</a>');
function generateAnchors(content) {
return content.replace(/(@([^ @]+))/ig, '<a href="/home/user/$2">$1</a>');
}
const input = 'foo @bar baz @qux @ @@@@@';
const output = generateAnchors(input);
console.log(output);