如何使用.split捕获的分隔符重新连接数组?

huangapple go评论72阅读模式
英文:

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 `&lt;span class=&quot;hyperlink&quot;&gt;&lt;/span&gt;`. */
  parseURLs(message) {
    if (!message) return &#39;&#39;;

    return message
      .split(/\s+/)
      .map(word =&gt; {
        console.log(&#39;test word:&#39;, word);
        try {
          const url = new URL(word);
          return `&lt;span class=&quot;hyperlink&quot;&gt;${word}&lt;/span&gt;`;
        } catch {
          return word;
        }
      })
      .join(&#39; &#39;);
  }

答案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(&#39;test3spaces   test1space testnospace https://www.google.com&#39;);
console.log(o);

function parseURLs(message) {
  if (!message) return &#39;&#39;;

  //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 =&gt; {
    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 = `&lt;span class=&quot;hyperlink&quot;&gt;${word}&lt;/span&gt;`;
    } catch {
      parsed.processed = word;
    }
    //**--
    
    return parsed;
  });    

  //returns the serialization of words array
  return words.reduce( (serialized, word) =&gt; serialized += `${word.processed}${word.separator}`, &#39;&#39;);
}

<!-- end snippet -->

答案2

得分: 1

你在分割时丢掉了空格,无法恢复。

英文:

You've thrown away the whitespace when splitting, you don't get that back.

function parseURLs(message) {
  return message &amp;&amp; message.replace(/\S+/g, word =&gt; {
    console.log(&#39;test word:&#39;, word);
    try {
      const url = new URL(word);
      return `&lt;span class=&quot;hyperlink&quot;&gt;${word}&lt;/span&gt;`;
    } catch (err) {
      return word;
    }
  });
}

huangapple
  • 本文由 发表于 2023年2月10日 16:54:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75408827.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定