簡體   English   中英

使用 javascript 如何遍歷正則表達式匹配並將字符串拆分為由超鏈接划分的片段數組?

[英]Using javascript how can I loop through regex matches and split string into array of pieces divided by hyperlinks?

我有一個從 api 中檢索到的字符串,如下所示:

"If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>."

我正在嘗試創建一個如下所示的數組:

[
 "If you "
 <a ... </a>
 " then "
 <a ... </a>
 "."
]

基本上我想按照預期的方式渲染它,而不僅僅是使用危險的設置 innerHtml 方法。 我已經有了我的正則表達式匹配我只是想找出最聰明的方法來循環它們並構建它。 我只是輸入了這個,但在看到它明顯有缺陷的輸出后意識到,我需要知道從哪里開始基於最后一次匹配的子字符串,但似乎無法解決如何解決這個問題。 任何指導表示贊賞

  let noticeTextArr: (string | JSX.Element)[] = [];
  if(notice.label !== undefined) {
    const reg = /<a.+?href="(.+?)".*?>(.+?)<\/a>/g;
    let result;
    while((result = reg.exec(notice.label)) !== null) {
      if(result.index > 0) {
        noticeTextArr.push(notice.label.substring(0, result.index))
      }
      noticeTextArr.push(<a href={result[1]}>{result[2]}</a>);      
    }
  }

這是一個有點令人毛骨悚然但工作良好的正則表達式。 這與您使用增強功能所做的方法基本相同。

function convertToJSX(text: string) {
  const regex = /<\s*a[^>]*href=["']([^>]*)["'][^>]*>(.*?)<\s*\/\s*a>/g;

  const matches = text.matchAll(regex);

  const noticeTextArr: (string | JSX.Element)[] = [];

  let lastIndex = 0;

  for (const match of matches) {
    const [fullMatch, href, content] = match;

    noticeTextArr.push(text.substring(lastIndex, match.index));
    noticeTextArr.push(<a href={href}>{content}</a>);

    lastIndex = match.index + fullMatch.length;
  }

  if (lastIndex < text.length) {
    noticeTextArr.push(text.substring(lastIndex));
  }

  return noticeTextArr;
}

你可以試試這個:

const text = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>.";

const array = text.split(/(<a.+?href=["'].+?["'].*?>.+?<\/a>)/g);

當您將正則表達式作為一個整體拆分時,js 會拆分文本,同時返回捕獲的組。 所以我更改了正則表達式以刪除內部組。

 const data = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>." const c = data.split(' ') let i = 0 let res = '' let arr = [] while(i< c.length){ if(c[i] === '<a') { arr.push(res) res = c[i] i++; while(!c[i].includes('</a>')) { res += " "+c[i] i++ } res += " "+c[i++] arr.push(res) res =''; } else { res +=" "+ c[i++] } } console.log(arr)

split與具有捕獲組的正則表達式一起使用:

 const text = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>."; console.log(text.split(/(<a\\s[^>]*>[^<]*<\\/a>)/));

看看正則表達式是如何工作的

解釋

                         EXPLANATION
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    <a                       '<a'
--------------------------------------------------------------------------------
    \s                       whitespace (\n, \r, \t, \f, and " ")
--------------------------------------------------------------------------------
    [^>]*                    any character except: '>' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    >                        '>'
--------------------------------------------------------------------------------
    [^<]*                    any character except: '<' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    <                        '<'
--------------------------------------------------------------------------------
    \/                       '/'
--------------------------------------------------------------------------------
    a>                       'a>'
--------------------------------------------------------------------------------
  )                        end of \1

因為很難解析 html 元素,我建議使用Document.createElement()以便讓瀏覽器解析和拆分您的文本:

 var txt = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>."; var el = document.createElement( 'html' ); el.innerHTML = txt; var result = Array.from(el.querySelector('body').childNodes).map(function(ele) { return ele.nodeType == Node.TEXT_NODE ? ele.textContent : ele.outerHTML; }); console.log(result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM