[C#] 取代字串中可能是網址的部分取代成超連結

2023-11-01

今天要聊一個小東西,但是花了我一點時間 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 這裡面有一些文章&#65292;網域是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<Match>() .Select(m => m.Value) .ToArray(); var resultString = testString; //先從長到短replace extracted = extracted.OrderByDescending(x => x.Length).ThenBy(x => x).ToArray(); //製作暫存 var tmpSwap = new Dictionary<string, string>(); 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] 這裡面有一些文章&#65292;網域是[6bb2309033de4bb194c98a329b0129f7] ,推薦一篇文章網址 [de4300c14d3c4278907833873ef63113] no https:開頭的網址是 [dd63a3e777d3402680c08a0db2b9b0de] //還原取代時候&#65292;從短到長還原&#65292;免得干擾 tmpSwap = tmpSwap.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value); foreach (var tmp in tmpSwap) { var url = tmp.Value; //判斷如果不是 http 開頭部分&#65292;在 href 的地方補上 https:// 免得變成相對路徑 if (!url.StartsWith("http")) { url = "https://" + url; } resultString = resultString.Replace(tmp.Key, "<a href="&quot; + url + &quot;">" + tmp.Value + "</a>"); } Console.WriteLine(resultString); //Welcome to <a href="http://blog.no2don.com">http://blog.no2don.com</a> 這裡面有一些文章&#65292;網域是<a href="https://blog.no2don.com">blog.no2don.com</a> ,推薦一篇文章網址 <a href="https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&amp;value=456">https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456</a> no https:開頭的網址是 <a href="https://blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&amp;value=456">blog.no2don.com/2023/10/javacsript-background-color-theif-make-invert-textcolor.html?id=123&value=456</a>


大概是這樣,其中得 regular expression 是我網路上東拼西湊的,有點找不到來源就沒有附上參考網站了,如果你有更好的解決方法或是套件,也歡迎提供給我

感謝


當麻許的碎念筆記 2014 | Donma Hsu Design.