今天要聊一個小東西,但是花了我一點時間 Regex 是真的不太熟,這需求很簡單,就是把一個字串,裡面可能是網址的部分,替換成超連結

這問題你一定覺得不就是用 Regex 搞一下就好了,話是這樣沒錯,但是當一個字串中,敘述到重覆的網域 有的有加上 http:// 有的沒有
就比較麻煩,不過可能是因為我 Regex 功力太差了,無法寫得更有效率
不過既然測試都測試了,就分享一下
這是我測試的字串 "Welcome to http://blog.no2don.com 這裡面有一些文章,網域是blog.no2don.com ,推薦一篇文章網址
https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456 no
https:開頭的網址是
blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456"
這裡面如果人類判斷,應該會看到四個網址分別是
http://blog.no2don.com
blog.no2don.com
https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456
blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456
這四個
這裡面我做的方法是先用 Regular Expression 過濾出可能的網址,之後根據找出來的網址長度從長排到短,並且給一個獨立的 uid 取代原本的字串
我是暫存先放入 Dictionary 中
像是變成
Welcome to [f0d9e3ddddfa403daf36ff81f3d554de] 這裡面有一些文章,網域是[4d9cf2e9dc0e48cea0debb60f0ff3b9d] ,推薦一篇文章網址
[3edd44baec634b8b840387dd892569cc] no https:開頭的網址是 [17ff79cabe89426897157eab0f7e7276]
之後再將 Dictionary 中的值長度由短排到長取代 並且加上關於 https:// 還有加入 <a> 的操作
Source Code:
var testString = @"Welcome to http://blog.no2don.com 這裡面有一些文章,網域是blog.no2don.com ,推薦一篇文章網址 https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456 no https:開頭的網址是 blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456";
var regexExpression = "(http|http(s)?://)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)";
Regex extractDateRegex = new Regex(regexExpression);
string[] extracted = extractDateRegex.Matches(testString)
.Cast()
.Select(m => m.Value)
.ToArray();
var resultString = testString;
//先從長到短replace
extracted = extracted.OrderByDescending(x => x.Length).ThenBy(x => x).ToArray();
//製作暫存
var tmpSwap = new Dictionary();
foreach (var replace in extracted)
{
var uid = Guid.NewGuid().ToString("N");
tmpSwap.Add("[" + uid + "]", replace);
resultString = resultString.Replace(replace, "[" + uid + "]");
}
Console.WriteLine(resultString);
//Welcome to [08afcd514c39429da2beb8dd629b41ea] 這裡面有一些文章,網域是[6bb2309033de4bb194c98a329b0129f7] ,推薦一篇文章網址 [de4300c14d3c4278907833873ef63113] no https:開頭的網址是 [dd63a3e777d3402680c08a0db2b9b0de]
//還原取代時候,從短到長還原,免得干擾
tmpSwap = tmpSwap.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
foreach (var tmp in tmpSwap)
{
var url = tmp.Value;
//判斷如果不是 http 開頭部分,在 href 的地方補上 https:// 免得變成相對路徑
if (!url.StartsWith("http"))
{
url = "https://" + url;
}
resultString = resultString.Replace(tmp.Key, "" + tmp.Value + "");
}
Console.WriteLine(resultString);
//Welcome to http://blog.no2don.com 這裡面有一些文章,網域是blog.no2don.com ,推薦一篇文章網址 https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456 no https:開頭的網址是 blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456
大概是這樣,其中得 regular expression 是我網路上東拼西湊的,有點找不到來源就沒有附上參考網站了,如果你有更好的解決方法或是套件,也歡迎提供給我
感謝