簡體   English   中英

如何編寫一個javascript正則表達式來替換此格式[*](*)的超鏈接與html超鏈接?

[英]How can I write a javascript regular expression to replace hyperlinks in this format [*](*) with html hyperlinks?

我需要使用以下格式的鏈接的解析文本:

[html title](http://www.htmlpage.com)
http://www.htmlpage.com
http://i.imgur.com/OgQ9Uaf.jpg

這兩個字符串的輸出將是:

<a href='http://www.htmlpage.com'>html title</a>
<a href='http://www.htmlpage.com'>http://www.htmlpage.com</a>
<a href='http://i.imgur.com/OgQ9Uaf.jpg'>http://i.imgur.com/OgQ9Uaf.jpg</a>

字符串可以包含任意數量的這些鏈接,即:

[html title](http://www.htmlpage.com)[html title](http://www.htmlpage.com)
[html title](http://www.htmlpage.com)   [html title](http://www.htmlpage.com)
[html title](http://www.htmlpage.com) wejwelfj http://www.htmlpage.com

輸出:

<a href='http://www.htmlpage.com'>html title</a><a href='http://www.htmlpage.com'>html title</a>
<a href='http://www.htmlpage.com'>html title</a>    <a href='http://www.htmlpage.com'>html title</a>
<a href='http://www.htmlpage.com'>html title</a> wejwelfj <a href='http://www.htmlpage.com'>http://www.htmlpage.com</a>

我有一個非常長的函數,通過傳遞字符串3次做一個正常的工作,但我無法成功解析此字符串:

[This](http://i.imgur.com/iIlhrEu.jpg) one got me crying first, then once the floodgates were opened [this](http://i.imgur.com/IwSNFVD.jpg) one did it again and [this](http://i.imgur.com/hxIwPKJ.jpg). Ugh, feels. Gotta go hug someone/something.

為簡潔起見,我將發布我嘗試過的正則表達式而不是整個查找/替換函數:

var matchArray2 = inString.match(/\[.*\]\(.*\)/g);

匹配[*](*) ,因為[]()[]()匹配不起作用

我猜,真的就是這樣。 一旦我進行了匹配,我搜索匹配的( )和[ ]來解析鏈接文本並構建href標記。 我從臨時字符串中刪除匹配項,因此當我第二次訪問以查找純超鏈接時,我不匹配它們:

var plainLinkArray = tempString2.match(/http\S*:\/\/\S*/g);

我沒有用正則表達式解析任何html。 我正在解析一個字符串並嘗試輸出html。

編輯:我之后添加了解析第三個鏈接http://i.imgur.com/OgQ9Uaf.jpg的要求。

我的最終解決方案(根據@ Cerbrus的回答):

function parseAndHandleHyperlinks(inString)
{
    var result = inString.replace(/\[(.+?)\]\((https?:\/\/.+?)\)/g, '<a href="$2">$1</a>');
    return result.replace(/(?: |^)(https?\:\/\/[a-zA-Z0-9/.(]+)/g, ' <a href="$1">$1</a>');     
}

試試這個正則表達式:

/\[(.+?)\]\((https?:\/\/[a-zA-Z0-9/.(]+?)\)/g

var s = "[html title](http://www.htmlpage.com)[html title](http://www.htmlpage.com)\n\
[html title](http://www.htmlpage.com)   [html title](http://www.htmlpage.com)\n\
[html title](http://www.htmlpage.com) wejwelfj http://www.htmlpage.com";

string.replace(/\[(.+?)\]\((https?:\/\/[a-zA-Z0-9/.(]+?)\)/g, '<a href="$2">$1</a>');

正則表達式說明:

# /                   - Regex Start
# \[                  - a `[` character (escaped)
# (.+?)               - Followed by any amount of words, grouped, non-greedy, so it won't match past:
# \]                  - a `]` character (escaped)
# \(                  - Followed by a `(` character (escaped)
# (https?:\/\/
#   [a-zA-Z0-9/.(]+?) - Followed by a string that starts with `http://` or `https://`
# \)                  - Followed by a `)` character (escaped)
# /g                  - End of the regex, search globally.

現在捕獲() / []中的2個字符串,並將其放在以下字符串中:

'<a href="$2">$1</a>';

這適用於您的“有問題”字符串:

var s = "[This](http://i.imgur.com/iIlhrEu.jpg) one got me crying first, then once the floodgates were opened [this](http://i.imgur.com/IwSNFVD.jpg) one did it again and [this](http://i.imgur.com/hxIwPKJ.jpg). Ugh, feels. Gotta go hug someone/something."
s.replace(/\[(.+?)\]\((https?:\/\/[a-zA-Z0-9/.(]+?)\)/g, '<a href="$2">$1</a>')

// Result:

'<a href="http://i.imgur.com/iIlhrEu.jpg">This</a> one got me crying first, then once the floodgates were opened <a href="http://i.imgur.com/IwSNFVD.jpg">this</a> one did it again and <a href="http://i.imgur.com/hxIwPKJ.jpg">this</a>. Ugh, feels. Gotta go hug someone/something.'

更多帶有“不正確”輸入的示例:

var s = "[Th][][is](http://x.com)\n\
    [this](http://x(.com)\n\
    [this](http://x).com)"
s.replace(/\[(.+?)\]\((https?:\/\/[a-zA-Z0-9/.(]+?)\)/g, '<a href="$2">$1</a>')

//   "<a href="http://x.com">Th][][is</a>
//    <a href="http://x(.com">this</a>
//    <a href="http://x">this</a>.com)"

你不能真的責怪破壞的最后一行,因為沒有辦法知道用戶是否打算在那里停止網址。

要捕獲松散的URL,請添加以下內容:

.replace(/(?: |^)(https?\:\/\/[a-zA-Z0-9/.(]+)/g, ' <a href="$1">$1</a>');

(?: |^)位捕獲String startspace字符,因此它也匹配以url開頭的行。

str.replace(/\[(.*?)\]\((.*?)\)/gi, '<a href="$2">$1</a>');

這假設URL中的字符串或括號中沒有錯誤的括號。

然后:

str.replace(/(\s|^)(https?:\/\/.*?)(?=\s|$)/gi, '$1<a href="$2">$2</a>')

這匹配一個類似“http”的URL,它不會立即在前面加上“(之前的替換就已經添加了)。當然,如果你擁有它,可以隨意使用更好的表達式。

編輯:我編輯了答案,因為我沒有意識到JS沒有lookbehind語法。 相反,您可以看到表達式匹配任何空格或行的開頭以匹配純http鏈接。 捕獲的空間必須放回(因此$1 )。 最后的一個前瞻是確保捕獲到下一個空格(或表達式的結尾)的所有內容。 如果空間對你來說不是一個好的邊界,你將不得不想出一個更好的邊界。

您似乎正在嘗試將Markdown語法轉換為HTML。 Markdown語法還沒有規范(我指的是語法,而不是行為規范),因此你將被蒙住眼睛走動並嘗試將bug修復程序納入你不想要的行為,所有這些在重新發明輪子的同時。 我建議您使用現有的實現,而不是自己編寫。 例如, Pagedown是Markdown的JS實現,目前在StackOverflow中使用。

如果你仍然想要一個正則表達式解決方案,下面是我的嘗試。 請注意,我不知道當你進步時它是否會與Markdown的其他功能很好地配合(如果你這樣做的話)。

/\[((?:[^\[\]\\]|\\.)+)\]\((https?:\/\/(?:[-A-Z0-9+&@#\/%=~_|\[\]](?= *\))|[-A-Z0-9+&@#\/%?=~_|\[\]!:,.;](?! *\))|\([-A-Z0-9+&@#\/%?=~_|\[\]!:,.;(]*\))+) *\)/i

上面的正則表達式應該捕獲一些部分(我不相信它捕獲所有內容,Pagedown的源代碼太復雜而無法一次性閱讀)Pagedown for [description](url)鏈接樣式(標題不是支持的)。 上面的正則表達式混合了Pagedown源代碼中使用的2個不同的正則表達式。

一些功能:

  • 捕獲組1包含[]內的文本,捕獲組2包含URL。
  • 允許通過使用\\ [a\\[1\\]](http://link.com)例如[a\\[1\\]](http://link.com)轉義文本部分[] ]內的[] 但是,您需要進行一些額外的處理。
  • 在鏈接中允許1級() ,在這種情況下非常有用: [String.valueOf](http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#valueOf(double))
  • 允許鏈接后和之前的空格)

我沒有考慮這個正則表達式中的裸鏈接。

參考:

暫無
暫無

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

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