英文:
How to rejoin array with caught separators from .split?
问题
/** 使用`<span class="hyperlink"></span>`将消息中找到的URL包装起来。 */
parseURLs(message) {
if (!message) return '';
return message
.split(/\s+/)
.map(word => {
console.log('test word:', word);
try {
const url = new URL(word);
return `<span class="hyperlink">${word}</span>`;
} catch {
return word;
}
})
.join(' ');
}
英文:
Below re-joins an array of words after splitting it with /\s+/
. But it only joins it with space, replacing the original separator caught in between. I want to return the original separator caught between words, like line-breaks which are also matched on the RegExp
expression.
/** wraps URLS found in message with `<span class="hyperlink"></span>`. */
parseURLs(message) {
if (!message) return '';
return message
.split(/\s+/)
.map(word => {
console.log('test word:', word);
try {
const url = new URL(word);
return `<span class="hyperlink">${word}</span>`;
} catch {
return word;
}
})
.join(' ');
}
答案1
得分: 2
以下是代码部分的翻译:
const o = parseURLs('test3spaces test1space testnospace https://www.google.com');
console.log(o);
function parseURLs(message) {
if (!message) return '';
// 用于匹配非空格字符后面的空格的正则表达式
const matches = message.matchAll(/(\S+)(\s*)/g);
// 将所有匹配结果存入words数组(每个元素是一个对象,包含fullmatch、word和separator属性)
const words = [...matches].map(match => {
const [fullmatch, word, separator] = match;
const parsed = {fullmatch, word, separator};
//**--[这是从您的代码片段中复制的单词转换逻辑]--**
try {
const url = new URL(word);
parsed.processed = `<span class="hyperlink">${word}</span>`;
} catch {
parsed.processed = word;
}
//**--
return parsed;
});
// 返回words数组的序列化结果
return words.reduce((serialized, word) => serialized += `${word.processed}${word.separator}`, '');
}
请注意,这是代码部分的翻译,不包括问题的回答。如果您需要其他部分的翻译,请提供明确的指示。
英文:
Since each word will have its own separator (as an arbitrary number of whitespaces) you can't rely on join
to serialize the array of words.
But if you change your parsing strategy so that instead of using split
you go straight with regular expressions, you can match your words followed by zero or * amount of whitespaces.
const matches = message.matchAll(/(\S+)(\s*)/g);
Then you can just loop the matches found and build your own array of objects like I did here as {fullmatch, word, separator}
.
In the end you can process this array as you best prefer and in the end serialize it back to string using for example reduce
*Here I also added your transform logic that will process the parsed word in .processed
so that it will be used during the serialization process but yet you will have all the parsed bits conserved in a structured way.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const o = parseURLs('test3spaces test1space testnospace https://www.google.com');
console.log(o);
function parseURLs(message) {
if (!message) return '';
//regex to match nonspace characters followed by spaces
const matches = message.matchAll(/(\S+)(\s*)/g);
//pushes all matches in words (as objects {fullmatch, word, separator})
const words = [...matches].map( match => {
const [fullmatch, word, separator] = match;
const parsed = {fullmatch, word, separator};
//**--[This is the trasform of the word as copied from your snippet]--**
try {
const url = new URL(word);
parsed.processed = `<span class="hyperlink">${word}</span>`;
} catch {
parsed.processed = word;
}
//**--
return parsed;
});
//returns the serialization of words array
return words.reduce( (serialized, word) => serialized += `${word.processed}${word.separator}`, '');
}
<!-- end snippet -->
答案2
得分: 1
你在分割时丢掉了空格,无法恢复。
英文:
You've thrown away the whitespace when splitting, you don't get that back.
function parseURLs(message) {
return message && message.replace(/\S+/g, word => {
console.log('test word:', word);
try {
const url = new URL(word);
return `<span class="hyperlink">${word}</span>`;
} catch (err) {
return word;
}
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论