字符串匹配正则表达式模式并替换为匹配的问题

Posted

技术标签:

【中文标题】字符串匹配正则表达式模式并替换为匹配的问题【英文标题】:Issue with string matching the Regex pattern and replacing with matched 【发布时间】:2020-07-12 01:25:29 【问题描述】:

要求包含dd/mm/yyyy hh:mm格式的表数据的字符串变量text2需要用="dd-MMM-yyyy HH:mm:ss"替换用双引号括起来的日期和时间

例如:25-Feb-2020 15:27:58需要替换成="25-Feb-2020 15:27:58"

DotNetFiddler

下面是完整的sn-p代码

using System;
using System.Text.RegularExpressions;


public class Program

    public static void Main()
    
        string text = "<table>\n  <thead><tr><th style=\"\"><div class=\"th-inner \">Login Name</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner sortable\">Registered</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner \">Registered Date <br>Time</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner sortable\">User Response Count</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner \">Test Start Date Time</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner \">Test End Date Time</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner \">Time Remaining</div><div class=\"fht-cell\"></div></th><th style=\"\"><div class=\"th-inner \">User Status</div><div class=\"fht-cell\"></div></th></tr></thead><tbody><tr data-index=\"9\"><td style=\"\">njuser14</td><td style=\"\">Yes</td><td style=\"\">-</td><td style=\"\">0</td><td style=\"\">29-Feb-2020 15:27:58</td><td style=\"\">29-Feb-2020 15:28:03</td><td style=\"\">179</td><td style=\"\">Paused</td></tr><tr data-index=\"10\"><td style=\"\">njuser15</td><td style=\"\">Yes</td><td style=\"\">-</td><td style=\"\">0</td><td style=\"\">29-Feb-2020 15:27:32</td><td style=\"\">29-Feb-2020 15:27:42</td><td style=\"\">179</td><td style=\"\">Paused</td></tr></tbody></table>";
        string text2 = " dasd arew 2017-03-11 12:25:56 2017-03-11 12:25:56 das tfgwe 2017-03-11 12:25:56 ";
        string pattern = @"\d4\-\d2\-\d2\s\d2\:\d2\:\d2";
        Regex r = new Regex(pattern);
        var res = r.Replace(text, new MatchEvaluator(ConvertDateFormat));
        var res2 = r.Replace(text2, new MatchEvaluator(ConvertDateFormat));
        Console.WriteLine(res);
        Console.WriteLine("-------------------------------------------------------");
        Console.WriteLine(res2);
    

    static string ConvertDateFormat(Match m)
    
        var mydate = DateTime.Parse(m.Value);
        return mydate.ToString("=yyyy-MM-dd hh:mm:ss");
    


// 29-Feb-2020 15:27:58 need to be replaced with ="29-Feb-2020 15:27:58"

结果:

<table>
  <thead><tr><th style=""><div class="th-inner ">Login Name</div><div class="fht-cell"></div></th><th style=""><div class="th-inner sortable">Registered</div><div class="fht-cell"></div></th><th style=""><div class="th-inner ">Registered Date <br>Time</div><div class="fht-cell"></div></th><th style=""><div class="th-inner sortable">User Response Count</div><div class="fht-cell"></div></th><th style=""><div class="th-inner ">Test Start Date Time</div><div class="fht-cell"></div></th><th style=""><div class="th-inner ">Test End Date Time</div><div class="fht-cell"></div></th><th style=""><div class="th-inner ">Time Remaining</div><div class="fht-cell"></div></th><th style=""><div class="th-inner ">User Status</div><div class="fht-cell"></div></th></tr></thead><tbody><tr data-index="9"><td style="">njuser14</td><td style="">Yes</td><td style="">-</td><td style="">0</td><td style="">29-Feb-2020 15:27:58</td><td style="">29-Feb-2020 15:28:03</td><td style="">179</td><td style="">Paused</td></tr><tr data-index="10"><td style="">njuser15</td><td style="">Yes</td><td style="">-</td><td style="">0</td><td style="">29-Feb-2020 15:27:32</td><td style="">29-Feb-2020 15:27:42</td><td style="">179</td><td style="">Paused</td></tr></tbody></table>
-------------------------------------------------------
 dasd arew =2017-03-11 12:25:56 =2017-03-11 12:25:56 das tfgwe =2017-03-11 12:25:56

但这里是字符串变量

    text2 值被替换为 =dd-MMM-yyyy HH:mm:ss。但不是 "=dd-MMM-yyyy HH:mm:ss" text 值保持不变。但不是 "=dd-MMM-yyyy HH:mm:ss"

【问题讨论】:

您是否希望 ToString("=yyyy-MM-dd hh:mm:ss") 中的双引号包含在您的替换文本中? @PeterM 是的。但是你怎么把ToString("="yyyy-MM-dd hh:mm:ss""); string.Format("=\"0\"", mydate.ToString("yyyy-MM-dd hh:mm:ss")) 试过了。但这对text Click here @JustinEzequiel 来说是行不通的 如果您没有在太长的 text 变量中隐藏其他日期时间字符串格式,那么我会看到您尝试了 两种不同的格式匹配一个正则表达式。试试string pattern = @"(?:\d4\-\d2\-\d2\s\d2\:\d2\:\d2)|(?:\d2-[A-Z][a-z]2-\d4 \d2\:\d2\:\d2)"; 【参考方案1】:

根据 cmets,第一个问题似乎是期望

return mydate.ToString("=yyyy-MM-dd hh:mm:ss");

将 DataTime 格式转换为字符串时将包含引号。但这些引号实际上是格式字符串本身的终止符,并不是格式字符串的一部分。

贾斯汀建议的解决方案

string.Format("=\"0\"", mydate.ToString("yyyy-MM-dd hh:mm:ss"))

虽然我的首选格式会使用字符串插值

$"\"mydate.ToString("yyyy-MM-dd hh:mm:ss")\""

第二个问题是 text 和 text2 的日期时间格式不同,提供的正则表达式只匹配 text2 中的格式

text:  29-Feb-2020 15:27:58 
text2: 2017-03-11 12:25:56 
regex: @"\d4\-\d2\-\d2\s\d2\:\d2\:\d2"

正则表达式匹配字符串并且不知道它们匹配的数据。所以一个简单的文本正则表达式就像(未经测试)

@"\d2\-[a-zA-Z]3\-\d4\s\d2\:\d2\:\d2"

这假定月份总是 3 个字符长,并且没有任何看起来像日期但不是日期的东西。

您的示例明确进行了 2 次不同的匹配,因此如果您这样做,那么您可以为每个 text 和 text2 创建一个新的正则表达式并进行多次替换。或者您可以尝试组合正则表达式,例如(未经测试):

@"\d4\-\d2\-\d2\s\d2\:\d2\:\d2|\d2\-[a-zA-Z]3\-\d4\s\d2\:\d2\:\d2"

【讨论】:

以上是关于字符串匹配正则表达式模式并替换为匹配的问题的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式位置匹配攻略【转】

正则表达式

通过正则表达式模式匹配使用 stringbuilder 替换多次出现的字符串

正则-简单的模式

re.sub

5.2.1 正则表达式语法与子模式扩展语法