来聊聊正则表达式

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了来聊聊正则表达式相关的知识,希望对你有一定的参考价值。

概念

正则表达式 是一种匹配输入文本的模式。.Net框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。

Regex 类

Regex 类用于表示一个正则表达式。下表列出了 Regex 类中一些常用的方法:

1 public bool IsMatch( string input ) 指示 Regex 构造函数中指定的正则表达式是否在指定的输入字符串中找到匹配项。

2 public bool IsMatch( string input, int startat ) 指示 Regex 构造函数中指定的正则表达式是否在指定的输入字符串中找到匹配项,从字符串中指定的开始位置开始。

3 public static bool IsMatch( string input, string pattern ) 指示指定的正则表达式是否在指定的输入字符串中找到匹配项。

4 public MatchCollection Matches( string input ) 在指定的输入字符串中搜索正则表达式的所有匹配项。

5 public string Replace( string input, string replacement ) 在指定的输入字符串中,把所有匹配正则表达式模式的所有匹配的字符串替换为指定的替换字符串。

6 public string[] Split( string input ) 把输入字符串分割为子字符串数组,根据在 Regex 构造函数中指定的正则表达式模式定义的位置进行分割。

例子

正则表达式的完全匹配

  public override void DoJob(IJobExecutionContext context, ILifetimeScope scope, string[] args)
        {
            var accountModuleMgmtService = scope.Resolve<IAccountModuleMgmtService>();
            // 取得所有使用過 BigCentral方案的帳號
            var bigCentralModuleAccountList = accountModuleMgmtService.GetList(
                    new AccountModuleMgmtSearchViewModel()
                    {
                        bundleTypes = new List<string> { BundleType.BigCentral, BundleType.BigCRM, BundleType.Feedback }
                    }
                ).Select(m => m.Account_Module_Mgmt.Account).Distinct();

            test
            //var bigCentralModuleAccountList = new List<string>();
            //bigCentralModuleAccountList.Add("S_Acct_90000618");
            

            Log($"bigCentralModuleAccountList.Count(): {bigCentralModuleAccountList.Count()}");

            //int executingCount = 0;
            int completedCount = 0;
            int totalCount = bigCentralModuleAccountList.Count();
            void LogProgress()
            {
                //Console.WriteLine($"{(completedCount / (decimal)totalCount).ToString("#0.00%")}  {new { executingCount, completedCount }.ToJsonString()}");
                Console.WriteLine($"{(completedCount / (decimal)totalCount).ToString("#0.00%")}, completedCount: {completedCount}");
            }

            List<(Regex pattern, string replacement, bool ishtml)> replacePatternList = new List<(Regex pattern, string replacement, bool isHtml)>
            {
                (new Regex(@"{{review_image_product_contact_link:(.*?)}}"), "{{review_link_5_star:$1}}", false),
                (new Regex(@"{{review_feedback_image_product_contact_link:(.*?)}}"), "{{review_link_5_star:$1}}", false),
                (new Regex(@"{{feedback_order_store_contact_link:(.*?)}}"), "{{feedback_link_5_star:$1}}", false),
                (new Regex("{{image_product_name_link}}"), "{{product_name}}", false),
                (new Regex("{{product_name_asin_link}}"), "{{product_name_asin}}", false),
                (new Regex("(\\\\<img.*?style=['\\"])([^\\\\>]+\\\\>)", RegexOptions.IgnoreCase), "$1max-width: 80% !important;$2", true),
                (new Regex("(max-width: 80% !important;)+", RegexOptions.IgnoreCase), "max-width: 80% !important;", true), // 移除排程多次執行,重複加入的樣式
            };
            List<(Regex pattern, string replacement, bool isHtml)> GetEffectivePatterList(string content, bool onlyText)
            {
                var effectivePatternList = replacePatternList
                    .FindAll(p => p.isHtml == (onlyText ? false : p.isHtml))
                    .FindAll(p => p.pattern.IsMatch(content));
                return effectivePatternList;
            }
            bool IsMatchContent(string content, bool onlyText = false)
            {
                if (string.IsNullOrWhiteSpace(content))
                {
                    return false;
                }

                return GetEffectivePatterList(content, onlyText).Any();
            }
            string ReplaceContent(string content, bool onlyText = false)
            {
                if (string.IsNullOrWhiteSpace(content))
                {
                    return content;
                }

                var effectivePatternList = GetEffectivePatterList(content, onlyText);
                foreach (var (pattern, replacement, isHtml) in effectivePatternList)
                {
                    content = pattern.Replace(content, replacement);
                }
                return content;
            }

正则表达式替换内容

  int.TryParse(GetArg(args, 1, "100"), out int maxDegreeOfParallelism);
            var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism };
            Parallel.ForEach(bigCentralModuleAccountList, parallelOptions, (account) =>
            {
                //System.Threading.Interlocked.Increment(ref executingCount); // 減少 lock縮短執行時間
                using (ILifetimeScope jobScope = AutofacConfig.Container.BeginLifetimeScope())
                using (new TimeMeasureScope($"account: {account}"))
                {
                    try
                    {
                        var setLoginStatus = jobScope.Resolve<ISetLoginStatus>(); //Login Status (Windows Service 要先執行)
                        setLoginStatus.SetAccount(account); //執行前要先設定 Account,才能找到對應的 SCH DB

                        #region User_Ticket_Draft

                        var userTicketDraftService = jobScope.Resolve<IUserTicketDraftService>();
                        var userTicketDraftList = userTicketDraftService.getUser_Ticket_Draft(account).ToList() ?? new List<User_Ticket_Draft>();
                        var validUserTicketDraftList = userTicketDraftList.FindAll(u =>
                            !string.IsNullOrEmpty(u?.DraftModelJsonString)
                        );
                        logger.Info($"{account}, userTicketDraftList.Count: {userTicketDraftList.Count}, validUserTicketDraftList: {validUserTicketDraftList.Count}");
                        foreach (var userTicketDraft in validUserTicketDraftList)
                        {
                            bool isUpdateUserTicketDraft = false;

                            string unzipJsonString = StringTools.UnzipZippedText(userTicketDraft.DraftModelJsonString);
                            List<TicketAddMessageModel> resultList = JsonConvert.DeserializeObject<List<TicketAddMessageModel>>(unzipJsonString);

                            if (resultList?.Any() == true)
                            {
                                foreach (var item in resultList.FindAll(r => IsMatchContent(r.Message)))
                                {
                                    item.Message = ReplaceContent(item.Message);
                                    isUpdateUserTicketDraft = true;
                                }
                            }

                            if (isUpdateUserTicketDraft)
                            {
                                string jsonString = JsonConvert.SerializeObject(resultList);
                                string zippedJsonString = StringTools.ZipText(jsonString);

                                userTicketDraft.DraftModelJsonString = zippedJsonString;
                                userTicketDraft.Update_Date = DateTime.UtcNow;
                                userTicketDraft.Update_User = nameof(ReleaseUpdate1381);

                                userTicketDraftService.updateUser_Ticket_Draft(userTicketDraft);
                            }
                        }

                        #endregion User_Ticket_Draft

                        #region TicketTemplateSub

                        var ticketTemplateService = jobScope.Resolve<ITicketTemplateService>();
                        var ticketTemplateSubList = ticketTemplateService.getTicket_Template_Sub(account).ToList() ?? new List<Ticket_Template_Sub>();
                        var modifyTicketTemplateSubList = ticketTemplateSubList.FindAll(t =>
                            IsMatchContent(t.Message_Html)
                            || IsMatchContent(t.Message_Text)
                        );
                        logger.Info($"{account}, ticketTemplateSubList.Count: {ticketTemplateSubList.Count}, modifyTicketTemplateSubList.Count: {modifyTicketTemplateSubList.Count}");
                        foreach (var ticketTemplateSub in modifyTicketTemplateSubList)
                        {
                            bool isupdate = false;

                            if (IsMatchContent(ticketTemplateSub.Message_Html))
                            {
                                ticketTemplateSub.Message_Html = ReplaceContent(ticketTemplateSub.Message_Html);
                                isupdate = true;
                            }

                            if (IsMatchContent(ticketTemplateSub.Message_Text))
                            {
                                ticketTemplateSub.Message_Text = ReplaceContent(ticketTemplateSub.Message_Text);
                                isupdate = true;
                            }

                            if (isupdate)
                            {
                                ticketTemplateSub.Update_Date = DateTime.UtcNow;
                                ticketTemplateSub.Update_User = nameof(ReleaseUpdate1381);
                                ticketTemplateService.UpdateTicket_Template_Sub(ticketTemplateSub);
                            }
                        }

                        #endregion TicketTemplateSub

                        #region Campaign Template

                        var amznFdbkMailCampaignTemplateService = jobScope.Resolve<IAmznFdbkMailCampaignTemplateService>();
                        lock (lockObj)
                        {
                            //刪除Campaign Template
                            amznFdbkMailCampaignTemplateService.DeleteCampaignTemplate(new AmznFdbkCampaignGuidSearchModel() { Account = account });
                        }
                        var allCampaigns = amznFdbkMailCampaignTemplateService.GetAllAMZN_Fdbk_Mail_Campaign_Template(account).ToList() ?? new List<AMZN_Fdbk_Mail_Campaign_Template>();
                        var modifyCampaigns = allCampaigns.FindAll(c =>
                            IsMatchContent(c.Template_Content)
                            || IsMatchContent(c.Template_Text_Content)
                            || IsMatchContent(c.Variable_List)
                        );
                        logger.Info($"{account}, allCampaigns.Count: {allCampaigns.Count}, modifyCampaigns.Count: {modifyCampaigns.Count}");
                        foreach (var campaign in modifyCampaigns)
                        {
                            bool isupdate = false;

                            if (IsMatchContent(campaign.Template_Content))
                            {
                                campaign.Template_Content = ReplaceContent(campaign.Template_Content);
                                isupdate = true;
                            }

                            if (IsMatchContent(campaign.Template_Text_Content))
                            {
                                campaign.Template_Text_Content = ReplaceContent(campaign.Template_Text_Content);
                                isupdate = true;
                            }

                            if (IsMatchContent(campaign.Variable_List, onlyText: true))
                            {
                                campaign.Variable_List = ReplaceContent(campaign.Variable_List, onlyText: true);
                                isupdate = true;
                            }

                            if (isupdate)
                            {
                                amznFdbkMailCampaignTemplateService.Update(campaign, nameof(ReleaseUpdate1381));
                            }
                        }

                        #endregion Campaign Template
                    }
                    catch (Exception e)
                    {
                        Log($"Catch exception. account: {account}, {e.ToString()}");
                    }
                }
                //System.Threading.Interlocked.Decrement(ref executingCount);
                System.Threading.Interlocked.Increment(ref completedCount);
                LogProgress();
            });
        }

        protected override string GetLoggerName()
        {
            return GetType().FullName;
        }
    }

    public static class ReplaceRegexIMG
    {
        public static string ReplacehtmlBody(string htmlBody)
        {
            if (string.IsNullOrWhiteSpace(htmlBody))
            {
                return htmlBody;
            }

            var reg = new System.Text.RegularExpressions.Regex("(\\\\<img.*?style=['\\"])([^\\\\>]+\\\\>)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            return reg.Replace(htmlBody, "$1max-width: 80% !important;$2");
        }
    }
}

以上是关于来聊聊正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

通过 Java 正则表达式提取 semver 版本字符串的片段

有问必答:聊聊正则表达式里的转义字符

text 正则表达式片段

markdown 正则表达式模式片段

正则表达式匹配特定的 URL 片段而不是所有其他 URL 可能性

python中正则表达式的使用