{"id":3538,"date":"2025-04-13T14:39:41","date_gmt":"2025-04-13T06:39:41","guid":{"rendered":"https:\/\/www.laixuexila.com\/?p=3538"},"modified":"2025-04-13T14:39:41","modified_gmt":"2025-04-13T06:39:41","slug":"c-%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%ef%bc%88regular-expressions%ef%bc%89","status":"publish","type":"post","link":"https:\/\/www.laixuexila.com\/index.php\/2025\/04\/13\/c-%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%ef%bc%88regular-expressions%ef%bc%89\/","title":{"rendered":"C# \u6b63\u5219\u8868\u8fbe\u5f0f\uff08Regular Expressions\uff09"},"content":{"rendered":"\n<p>\u672c\u7ae0\u8282\u91cd\u70b9\u8bb2\u89e3 <strong>C# \u6b63\u5219\u8868\u8fbe\u5f0f\uff08Regular Expressions\uff09<\/strong> \uff0c\u5305\u62ec\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u57fa\u672c\u539f\u7406<\/li>\n\n\n\n<li>\u5e38\u7528\u65b9\u6cd5\u548c\u7c7b<\/li>\n\n\n\n<li>\u5b9e\u4f8b\u8bb2\u89e3<\/li>\n\n\n\n<li>\u5339\u914d\u6a21\u5f0f\u8bf4\u660e<\/li>\n\n\n\n<li>\u6027\u80fd\u4f18\u5316\u5efa\u8bae<\/li>\n\n\n\n<li>\u591a\u9014\u5f84\u5b9e\u8df5\u65b9\u6cd5<\/li>\n\n\n\n<li>\u5b98\u65b9\u6587\u6863\u94fe\u63a5<\/li>\n\n\n\n<li>\u5b9e\u6218\u6848\u4f8b<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e00\u3001 \u4ec0\u4e48\u662f\u6b63\u5219\u8868\u8fbe\u5f0f\uff1f<\/h2>\n\n\n\n<p>\u6b63\u5219\u8868\u8fbe\u5f0f\u662f\u4e00\u79cd\u7528\u4e8e\u63cf\u8ff0\u6587\u672c\u6a21\u5f0f\u7684\u5b57\u7b26\u4e32\u89c4\u5219\uff0c\u53ef\u4ee5\u9ad8\u6548\u5730\u6267\u884c\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5b57\u7b26\u4e32\u5339\u914d<\/li>\n\n\n\n<li>\u5b57\u7b26\u4e32\u63d0\u53d6<\/li>\n\n\n\n<li>\u5b57\u7b26\u4e32\u66ff\u6362<\/li>\n\n\n\n<li>\u8f93\u5165\u9a8c\u8bc1\u7b49\u4efb\u52a1<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e8c\u3001\u6240\u7528\u547d\u540d\u7a7a\u95f4\u4e0e\u7c7b<\/h2>\n\n\n\n<p>C# \u4e2d\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u9700\u5f15\u7528\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using System.Text.RegularExpressions;<\/code><\/pre>\n\n\n\n<p>\u6838\u5fc3\u7c7b\u5982\u4e0b\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u7c7b\u540d<\/th><th>\u529f\u80fd<\/th><\/tr><\/thead><tbody><tr><td><code>Regex<\/code><\/td><td>\u6b63\u5219\u8868\u8fbe\u5f0f\u4e3b\u7c7b<\/td><\/tr><tr><td><code>Match<\/code><\/td><td>\u8868\u793a\u4e00\u6b21\u5339\u914d\u7ed3\u679c<\/td><\/tr><tr><td><code>MatchCollection<\/code><\/td><td>\u8868\u793a\u591a\u4e2a\u5339\u914d\u7ed3\u679c<\/td><\/tr><tr><td><code>Group<\/code><\/td><td>\u5339\u914d\u7ed3\u679c\u7684\u5b50\u8868\u8fbe\u5f0f<\/td><\/tr><tr><td><code>RegexOptions<\/code><\/td><td>\u63a7\u5236\u5339\u914d\u884c\u4e3a\u7684\u679a\u4e3e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e09\u3001\u5e38\u7528\u6784\u9020\u51fd\u6570\u4e0e\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 \u521b\u5efa Regex \u5b9e\u4f8b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Regex regex = new Regex(@\"\\d+\");  \/\/ \u5339\u914d\u6570\u5b57<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 \u9759\u6001\u65b9\u6cd5\uff08\u63a8\u8350\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>bool isMatch = Regex.IsMatch(\"abc123\", @\"\\d+\"); \/\/ true\nstring&#91;] result = Regex.Split(\"one,two;three\", @\"&#91;,;]\");\nstring replaced = Regex.Replace(\"hello 123\", @\"\\d+\", \"###\");\nMatch match = Regex.Match(\"abc123def\", @\"\\d+\");<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u56db\u3001\u5e38\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u8bed\u6cd5<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u8868\u8fbe\u5f0f<\/th><th>\u5339\u914d\u5185\u5bb9<\/th><\/tr><\/thead><tbody><tr><td><code>.<\/code><\/td><td>\u4efb\u610f\u5355\u5b57\u7b26\uff08\u4e0d\u542b\u6362\u884c\uff09<\/td><\/tr><tr><td><code>\\d<\/code><\/td><td>\u6570\u5b57\uff080-9\uff09<\/td><\/tr><tr><td><code>\\w<\/code><\/td><td>\u5355\u8bcd\u5b57\u7b26\uff08\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\uff09<\/td><\/tr><tr><td><code>\\s<\/code><\/td><td>\u7a7a\u767d\u5b57\u7b26<\/td><\/tr><tr><td><code>^<\/code><\/td><td>\u5f00\u59cb\u4f4d\u7f6e<\/td><\/tr><tr><td><code>$<\/code><\/td><td>\u7ed3\u675f\u4f4d\u7f6e<\/td><\/tr><tr><td><code>[abc]<\/code><\/td><td>\u5339\u914d a\u3001b \u6216 c<\/td><\/tr><tr><td><code>[^abc]<\/code><\/td><td>\u4e0d\u5339\u914d a\u3001b\u3001c<\/td><\/tr><tr><td><code>(abc)<\/code><\/td><td>\u6355\u83b7\u7ec4<\/td><\/tr><tr><td><code>a|b<\/code><\/td><td>a \u6216 b<\/td><\/tr><tr><td><code>{n}<\/code><\/td><td>\u91cd\u590d n \u6b21<\/td><\/tr><tr><td><code>?<\/code><\/td><td>\u53ef\u6709\u53ef\u65e0\uff080\u62161\u6b21\uff09<\/td><\/tr><tr><td><code>*<\/code><\/td><td>\u4efb\u610f\u6b21\u6570<\/td><\/tr><tr><td><code>+<\/code><\/td><td>\u81f3\u5c11 1 \u6b21<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e94\u3001\u793a\u4f8b\uff1a\u5e38\u89c1\u6b63\u5219\u8868\u8fbe\u5f0f<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u7528\u9014<\/th><th>\u6b63\u5219\u8868\u8fbe\u5f0f<\/th><\/tr><\/thead><tbody><tr><td>\u90ae\u7bb1<\/td><td><code>^[\\w.-]+@[\\w.-]+\\.\\w{2,}$<\/code><\/td><\/tr><tr><td>\u624b\u673a\u53f7\uff08\u4e2d\u56fd\uff09<\/td><td><code>^1[3-9]\\d{9}$<\/code><\/td><\/tr><tr><td>IPv4 \u5730\u5740<\/td><td><code>^(\\d{1,3}\\.){3}\\d{1,3}$<\/code><\/td><\/tr><tr><td>\u8eab\u4efd\u8bc1\u53f7\uff08\u7b80\u7565\uff09<\/td><td><code>^\\d{15}|\\d{18}$<\/code><\/td><\/tr><tr><td>\u65e5\u671f\uff08YYYY-MM-DD\uff09<\/td><td><code>^\\d{4}-\\d{2}-\\d{2}$<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u516d\u3001Match \u793a\u4f8b\uff08\u6355\u83b7\u6570\u636e\uff09<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>string text = \"Name: Alice, Age: 30\";\nMatch match = Regex.Match(text, @\"Name:\\s(\\w+),\\sAge:\\s(\\d+)\");\n\nif (match.Success)\n{\n    string name = match.Groups&#91;1].Value;\n    string age = match.Groups&#91;2].Value;\n    Console.WriteLine($\"Name: {name}, Age: {age}\");\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e03\u3001RegexOptions\uff08\u5339\u914d\u9009\u9879\uff09<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>Regex.IsMatch(\"abc\", \"ABC\", RegexOptions.IgnoreCase);  \/\/ \u5ffd\u7565\u5927\u5c0f\u5199\nRegex.IsMatch(\"abc\\ndef\", \"^def\", RegexOptions.Multiline);  \/\/ \u591a\u884c\u5339\u914d<\/code><\/pre>\n\n\n\n<p>\u5e38\u7528\u679a\u4e3e\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u679a\u4e3e\u540d<\/th><th>\u529f\u80fd<\/th><\/tr><\/thead><tbody><tr><td><code>IgnoreCase<\/code><\/td><td>\u4e0d\u533a\u5206\u5927\u5c0f\u5199<\/td><\/tr><tr><td><code>Multiline<\/code><\/td><td>\u591a\u884c\u6a21\u5f0f<\/td><\/tr><tr><td><code>Singleline<\/code><\/td><td><code>.<\/code> \u5339\u914d\u6362\u884c<\/td><\/tr><tr><td><code>Compiled<\/code><\/td><td>\u7f16\u8bd1\u6210\u7a0b\u5e8f\u96c6\uff08\u6027\u80fd\u4f18\u5316\uff09<\/td><\/tr><tr><td><code>CultureInvariant<\/code><\/td><td>\u5ffd\u7565\u533a\u57df\u6027\u6587\u5316\u8bbe\u7f6e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u516b\u3001\u6027\u80fd\u4f18\u5316\u5efa\u8bae<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5c3d\u91cf\u4f7f\u7528\u9759\u6001\u65b9\u6cd5\uff08\u907f\u514d\u9891\u7e41\u521b\u5efa <code>Regex<\/code> \u5b9e\u4f8b\uff09<\/li>\n\n\n\n<li>\u4f7f\u7528 <code>RegexOptions.Compiled<\/code> \u9884\u7f16\u8bd1\u8868\u8fbe\u5f0f\uff08\u9002\u5408\u5927\u91cf\u8c03\u7528\uff09<\/li>\n\n\n\n<li>\u7b80\u5316\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u907f\u514d\u5d4c\u5957\u8fc7\u6df1<\/li>\n\n\n\n<li>\u4f7f\u7528 <code>Timeout<\/code> \u9632\u6b62 ReDoS\uff08\u6b63\u5219\u62d2\u7edd\u670d\u52a1\u653b\u51fb\uff09<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>Regex regex = new Regex(@\"\\d+\", RegexOptions.Compiled, TimeSpan.FromSeconds(1));<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e5d\u3001\u5b9e\u6218\u6848\u4f8b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u6355\u83b7\u7ec4\u4e0e\u547d\u540d\u7ec4\u8be6\u89e3<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u533f\u540d\u6355\u83b7\u7ec4 <code>()<\/code><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>Match m = Regex.Match(\"2025-04-13\", @\"(\\d{4})-(\\d{2})-(\\d{2})\");\nConsole.WriteLine(m.Groups&#91;1].Value);  \/\/ \u5e74\nConsole.WriteLine(m.Groups&#91;2].Value);  \/\/ \u6708\nConsole.WriteLine(m.Groups&#91;3].Value);  \/\/ \u65e5<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u547d\u540d\u6355\u83b7\u7ec4 <code>(?&lt;name&gt;...)<\/code><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>string pattern = @\"(?&lt;year&gt;\\d{4})-(?&lt;month&gt;\\d{2})-(?&lt;day&gt;\\d{2})\";\nMatch match = Regex.Match(\"2025-04-13\", pattern);\nConsole.WriteLine(match.Groups&#91;\"year\"].Value);  \/\/ \u8f93\u51fa 2025<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u5b9e\u6218\u6848\u4f8b1\uff1a\u8868\u5355\u9a8c\u8bc1\uff08\u90ae\u7bb1 + \u624b\u673a\uff09<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u573a\u666f\uff1a\u5728\u6ce8\u518c\u9875\u9762\u4e2d\u9a8c\u8bc1\u7528\u6237\u8f93\u5165<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>string email = \"user@example.com\";\nstring phone = \"13812345678\";\n\nbool validEmail = Regex.IsMatch(email, @\"^&#91;\\w\\.-]+@&#91;\\w\\.-]+\\.\\w{2,}$\");\nbool validPhone = Regex.IsMatch(phone, @\"^1&#91;3-9]\\d{9}$\");\n\nConsole.WriteLine($\"\u90ae\u7bb1\u5408\u6cd5\uff1a{validEmail}, \u624b\u673a\u5408\u6cd5\uff1a{validPhone}\");<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u5b9e\u6218\u6848\u4f8b2\uff1a\u4ece\u65e5\u5fd7\u4e2d\u63d0\u53d6\u65f6\u95f4\u4e0eIP<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u573a\u666f\uff1a\u65e5\u5fd7\u5206\u6790\u7cfb\u7edf\uff0c\u62bd\u53d6\u65f6\u95f4\u6233\u4e0e IP<\/h4>\n\n\n\n<p><strong>\u65e5\u5fd7\u5185\u5bb9\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;2025-04-13 15:42:10] INFO Request from 192.168.1.55 processed.<\/code><\/pre>\n\n\n\n<p><strong>\u63d0\u53d6\u4ee3\u7801\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>string log = \"&#91;2025-04-13 15:42:10] INFO Request from 192.168.1.55 processed.\";\nstring pattern = @\"\\&#91;(?&lt;datetime&gt;.+?)\\].+?(?&lt;ip&gt;\\d+\\.\\d+\\.\\d+\\.\\d+)\";\n\nMatch m = Regex.Match(log, pattern);\nConsole.WriteLine($\"\u65f6\u95f4: {m.Groups&#91;\"datetime\"].Value}, IP: {m.Groups&#91;\"ip\"].Value}\");<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u5b9e\u6218\u6848\u4f8b3\uff1a\u6279\u91cf\u4ece\u6587\u4ef6\u4e2d\u63d0\u53d6\u90ae\u7bb1\u5730\u5740<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>string&#91;] lines = File.ReadAllLines(\"sample.txt\");\nRegex regex = new Regex(@\"&#91;\\w\\.-]+@&#91;\\w\\.-]+\\.\\w+\");\n\nforeach (string line in lines)\n{\n    foreach (Match m in regex.Matches(line))\n    {\n        Console.WriteLine($\"\u627e\u5230\u90ae\u7bb1: {m.Value}\");\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">5. \u5b9e\u6218\u6848\u4f8b4\uff1a\u7f51\u9875\u722c\u866b\u4e2d\u63d0\u53d6\u8d85\u94fe\u63a5<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>string html = \"&lt;a href=\\\"https:\/\/example.com\\\"&gt;Example&lt;\/a&gt;\";\nstring pattern = @\"&lt;a\\s+&#91;^&gt;]*href\\s*=\\s*&#91;\"\"']?(?&lt;url&gt;&#91;^\"\"'&gt;\\s]+)&#91;\"\"']?\";\n\nMatchCollection matches = Regex.Matches(html, pattern);\n\nforeach (Match match in matches)\n{\n    Console.WriteLine($\"URL: {match.Groups&#91;\"url\"].Value}\");\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">6. \u5b9e\u6218\u6848\u4f8b5\uff1a\u4e0e ASP.NET Core \u8868\u5355\u9a8c\u8bc1\u7ed3\u5408<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;RegularExpression(@\"^\\d{15}|\\d{18}$\", ErrorMessage = \"\u8eab\u4efd\u8bc1\u683c\u5f0f\u4e0d\u6b63\u786e\")]\npublic string IDCard { get; set; }<\/code><\/pre>\n\n\n\n<p>\u914d\u5408\u524d\u7aef Blazor \u6216 Razor Pages \u81ea\u52a8\u9a8c\u8bc1\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">7. \u4f7f\u7528 MatchEvaluator \u52a8\u6001\u66ff\u6362<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>string input = \"\u4ef7\u683c\u4e3a\uff1a$100, $200\";\nstring result = Regex.Replace(input, @\"\\$(\\d+)\", m =&gt;\n{\n    int price = int.Parse(m.Groups&#91;1].Value);\n    return $\"\uffe5{price * 7}\";\n});\nConsole.WriteLine(result);  \/\/ \u4ef7\u683c\u4e3a\uff1a\uffe5700, \uffe51400<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">8. \u6027\u80fd\u4f18\u5316\u5efa\u8bae<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u6280\u672f<\/th><th>\u5efa\u8bae<\/th><\/tr><\/thead><tbody><tr><td>\u7f16\u8bd1\u4f18\u5316<\/td><td>\u4f7f\u7528 <code>RegexOptions.Compiled<\/code><\/td><\/tr><tr><td>\u8868\u8fbe\u5f0f\u7f13\u5b58<\/td><td>\u53ef\u9759\u6001\u5b9a\u4e49 Regex \u5bf9\u8c61\uff0c\u907f\u514d\u91cd\u590d\u7f16\u8bd1<\/td><\/tr><tr><td>\u8d85\u65f6\u63a7\u5236<\/td><td>\u63a8\u8350\u8bbe\u7f6e\u8d85\u65f6\u9650\u5236\u9632\u6b62 ReDoS \u653b\u51fb<\/td><\/tr><tr><td>\u7b80\u6d01\u8bbe\u8ba1<\/td><td>\u6b63\u5219\u5c3d\u91cf\u907f\u514d\u4f7f\u7528\u56de\u6eaf\u8f83\u591a\u7684\u5199\u6cd5\uff08\u5982\u5d4c\u5957 <code>*+?<\/code>\uff09<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>Regex regex = new Regex(@\"\\d+\", RegexOptions.Compiled, TimeSpan.FromSeconds(1));<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5341\u3001\u771f\u5b9e\u9879\u76ee\u573a\u666f + \u6280\u672f\u96c6\u6210\u6307\u5357<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u5b9e\u6218\u6848\u4f8b\uff1a<strong>\u5b8c\u6574\u7684\u8868\u5355\u9a8c\u8bc1\u7cfb\u7edf\uff08ASP.NET Core MVC\uff09<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u573a\u666f\uff1a\u7528\u6237\u6ce8\u518c\u9875\u9762\u9a8c\u8bc1\u7528\u6237\u540d\u3001\u5bc6\u7801\u3001\u624b\u673a\u53f7\u3001\u90ae\u7bb1<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">\ud83d\udccc \u6a21\u578b\u5b9a\u4e49\uff08Models\/UserViewModel.cs\uff09<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>public class UserViewModel\n{\n    &#91;Required]\n    &#91;RegularExpression(@\"^&#91;a-zA-Z]&#91;a-zA-Z0-9_]{4,15}$\", ErrorMessage = \"\u7528\u6237\u540d\u5fc5\u987b\u4e3a5-16\u4f4d\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\")]\n    public string Username { get; set; }\n\n    &#91;Required]\n    &#91;RegularExpression(@\"^(?=.*&#91;A-Za-z])(?=.*\\d)&#91;A-Za-z\\d]{6,20}$\", ErrorMessage = \"\u5bc6\u7801\u5fc5\u987b\u4e3a6-20\u4f4d\u5b57\u6bcd\u548c\u6570\u5b57\u7ec4\u5408\")]\n    public string Password { get; set; }\n\n    &#91;Required]\n    &#91;RegularExpression(@\"^1&#91;3-9]\\d{9}$\", ErrorMessage = \"\u65e0\u6548\u7684\u624b\u673a\u53f7\")]\n    public string PhoneNumber { get; set; }\n\n    &#91;Required]\n    &#91;EmailAddress]\n    public string Email { get; set; }\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">\ud83d\udccc \u63a7\u5236\u5668\u9a8c\u8bc1\u903b\u8f91<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;HttpPost]\npublic IActionResult Register(UserViewModel model)\n{\n    if (!ModelState.IsValid)\n        return View(model);\n\n    \/\/ \u6ce8\u518c\u6210\u529f\u903b\u8f91\n    return RedirectToAction(\"Success\");\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">\ud83d\udccc \u89c6\u56fe\u8868\u5355\uff08Razor\uff09<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;form asp-action=\"Register\"&gt;\n    &lt;input asp-for=\"Username\" \/&gt;\n    &lt;span asp-validation-for=\"Username\"&gt;&lt;\/span&gt;\n    &lt;!-- \u5176\u4ed6\u5b57\u6bb5... --&gt;\n&lt;\/form&gt;<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u5b9e\u6218\u6848\u4f8b\uff1a<strong>\u6279\u91cf\u6821\u9a8c\u5e76\u91cd\u5199 CSV \u6587\u4ef6\u5b57\u6bb5<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u573a\u666f\uff1a\u8bc6\u522b\u65e0\u6548\u90ae\u7bb1\u5e76\u6807\u8bb0\u4e3a\u201c\u65e0\u6548\u90ae\u7bb1\u201d<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>string&#91;] lines = File.ReadAllLines(\"users.csv\");\nRegex emailRegex = new Regex(@\"^&#91;\\w\\.-]+@&#91;\\w\\.-]+\\.\\w{2,}$\");\n\nList&lt;string&gt; updated = new();\n\nforeach (string line in lines)\n{\n    var fields = line.Split(',');\n    if (!emailRegex.IsMatch(fields&#91;2])) \/\/ \u5047\u8bbe\u7b2c3\u5217\u662f\u90ae\u7bb1\n    {\n        fields&#91;2] = \"\u65e0\u6548\u90ae\u7bb1\";\n    }\n    updated.Add(string.Join(\",\", fields));\n}\n\nFile.WriteAllLines(\"users_clean.csv\", updated);<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u5b9e\u6218\u6848\u4f8b\uff1a<strong>\u65e5\u5fd7\u7cfb\u7edf\u6b63\u5219\u5339\u914d + LINQ \u6574\u5408\u5904\u7406<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>string&#91;] logs = File.ReadAllLines(\"app.log\");\nRegex logRegex = new Regex(@\"\\&#91;(?&lt;level&gt;INFO|ERROR|DEBUG)\\]\\s+(?&lt;message&gt;.+)\");\n\nvar errors = logs\n    .Select(line =&gt; logRegex.Match(line))\n    .Where(m =&gt; m.Success &amp;&amp; m.Groups&#91;\"level\"].Value == \"ERROR\")\n    .Select(m =&gt; m.Groups&#91;\"message\"].Value);\n\nforeach (var err in errors)\n    Console.WriteLine($\"\u274c \u9519\u8bef\uff1a{err}\");<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u5b9e\u6218\u6848\u4f8b\uff1a<strong>RESTful API \u63a5\u53e3\u4e2d\u6b63\u5219\u9a8c\u8bc1\u4e0a\u4f20\u6570\u636e<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;HttpPost]\npublic IActionResult Upload(&#91;FromBody] JObject data)\n{\n    string name = data&#91;\"name\"]?.ToString() ?? \"\";\n    string email = data&#91;\"email\"]?.ToString() ?? \"\";\n\n    if (!Regex.IsMatch(name, @\"^&#91;\\u4e00-\\u9fa5a-zA-Z\\s]{2,20}$\"))\n        return BadRequest(\"\u59d3\u540d\u683c\u5f0f\u4e0d\u5408\u6cd5\");\n\n    if (!Regex.IsMatch(email, @\"^&#91;\\w\\.-]+@&#91;\\w\\.-]+\\.\\w+$\"))\n        return BadRequest(\"\u90ae\u7bb1\u683c\u5f0f\u4e0d\u5408\u6cd5\");\n\n    return Ok(\"\u2705 \u4e0a\u4f20\u6210\u529f\");\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">5. \u5b9e\u7528\u6280\u5de7\uff1a\u7f16\u8bd1\u6b63\u5219 + \u7f13\u5b58\u673a\u5236\u63d0\u5347\u6027\u80fd<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>private static readonly Regex _urlRegex = new Regex(@\"https?:\/\/&#91;^\\s]+\", \n    RegexOptions.Compiled | RegexOptions.IgnoreCase);\n\npublic static IEnumerable&lt;string&gt; ExtractUrls(string content)\n{\n    return _urlRegex.Matches(content).Select(m =&gt; m.Value);\n}<\/code><\/pre>\n\n\n\n<p><strong>\u63a8\u8350\u4f7f\u7528\u7f16\u8bd1\u6b63\u5219 <code>RegexOptions.Compiled<\/code> + \u9759\u6001\u5b57\u6bb5\u7f13\u5b58<\/strong>\uff0c\u5c24\u5176\u5728\u9ad8\u9891\u8c03\u7528\u4e2d\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">6. \u6b63\u5219\u8868\u8fbe\u5f0f\u5de5\u5177\u7c7b\u5c01\u88c5\uff08\u590d\u7528\u6027\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>public static class RegexUtils\n{\n    private static Regex phoneRegex = new(@\"^1&#91;3-9]\\d{9}$\", RegexOptions.Compiled);\n    private static Regex emailRegex = new(@\"^&#91;\\w\\.-]+@&#91;\\w\\.-]+\\.\\w+$\", RegexOptions.Compiled);\n\n    public static bool IsValidPhone(string input) =&gt; phoneRegex.IsMatch(input);\n    public static bool IsValidEmail(string input) =&gt; emailRegex.IsMatch(input);\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">7. \u5b89\u5168\u4e0e\u6027\u80fd\u6ce8\u610f\u4e8b\u9879<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u4e8b\u9879<\/th><th>\u8bf4\u660e<\/th><\/tr><\/thead><tbody><tr><td>\u907f\u514d ReDoS<\/td><td>\u4f7f\u7528 <code>Regex<\/code> \u6784\u9020\u51fd\u6570\u6307\u5b9a <code>TimeSpan timeout<\/code><\/td><\/tr><tr><td>\u5c3d\u91cf\u907f\u514d <code>.*?<\/code> \u5d4c\u5957<\/td><td>\u53ef\u80fd\u5bfc\u81f4\u56de\u6eaf\u7206\u70b8<\/td><\/tr><tr><td>\u4f7f\u7528 <code>RegexOptions.Compiled<\/code><\/td><td>\u63d0\u5347\u6027\u80fd\uff0c\u907f\u514d\u9891\u7e41\u89e3\u6790<\/td><\/tr><tr><td>\u8868\u8fbe\u5f0f\u9a8c\u8bc1\u6d4b\u8bd5<\/td><td>\u4f7f\u7528 <a href=\"https:\/\/regex101.com\/?flavor=dotnet\">Regex101<\/a> \u6216 Visual Studio \u7684 Regex \u7f16\u8f91\u5668\u8c03\u8bd5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5341\u4e00\u3001\u63a8\u8350\u5de5\u5177\u53ca\u8d44\u6e90<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/zh-cn\/dotnet\/standard\/base-types\/regular-expressions\">Microsoft \u6b63\u5219\u8868\u8fbe\u5f0f\u6587\u6863\uff08\u4e2d\u6587\uff09<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/regex101.com\/?flavor=dotnet\">Regex101 \u5728\u7ebf\u6d4b\u8bd5\u5de5\u5177<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/owasp.org\/www-community\/attacks\/Regular_expression_Denial_of_Service_-_ReDoS\">OWASP ReDoS \u5b89\u5168\u5efa\u8bae<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/dotnet\/runtime\/tree\/main\/src\/libraries\/System.Text.RegularExpressions\">Regex in .NET GitHub Source<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/regex101.com\/\">Regex101<\/a>\uff08\u652f\u6301 C# \u6a21\u5f0f\uff09<\/li>\n\n\n\n<li><a href=\"https:\/\/www.debuggex.com\/\">Debuggex<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/regular-expression-language-quick-reference\">Microsoft \u6b63\u5219\u8868\u8fbe\u5f0f\u8bed\u6cd5\u53c2\u8003<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5341\u4e8c\u3001\u5b98\u65b9\u6587\u6863\u94fe\u63a5<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud83d\udcd8 <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.text.regularexpressions.regex\">Regex \u7c7b &#8211; Microsoft Learn<\/a><\/li>\n\n\n\n<li>\ud83d\udcd8 <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/regular-expression-language-quick-reference\">\u6b63\u5219\u8868\u8fbe\u5f0f\u8bed\u8a00\u5feb\u901f\u53c2\u8003<\/a><\/li>\n\n\n\n<li>\ud83d\udcd8 <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/regular-expressions\">.NET \u4e2d\u7684\u6b63\u5219\u8868\u8fbe\u5f0f<\/a><\/li>\n<\/ul>\n\n\n\n<p>\u66f4\u591a\u8be6\u7ec6\u5185\u5bb9\u8bf7\u5173\u6ce8\u5176\u4ed6\u76f8\u5173\u6587\u7ae0\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u7ae0\u8282\u91cd\u70b9\u8bb2\u89e3 C# \u6b63\u5219\u8868\u8fbe\u5f0f\uff08Regular Expressions\uff09 \uff0c\u5305\u62ec\uff1a \u4e00\u3001 \u4ec0\u4e48\u662f\u6b63\u5219\u8868\u8fbe\u5f0f\uff1f [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3539,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83],"tags":[],"class_list":["post-3538","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-"],"_links":{"self":[{"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/posts\/3538","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/comments?post=3538"}],"version-history":[{"count":1,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/posts\/3538\/revisions"}],"predecessor-version":[{"id":3540,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/posts\/3538\/revisions\/3540"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/media\/3539"}],"wp:attachment":[{"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/media?parent=3538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/categories?post=3538"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.laixuexila.com\/index.php\/wp-json\/wp\/v2\/tags?post=3538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}