【问题标题】:Regex to remove line break when next line does not start with a given string当下一行不以给定字符串开头时,正则表达式删除换行符
【发布时间】:2018-03-11 22:06:03
【问题描述】:

在 .net 中工作,我正在解析一个日志文件,其中某些行不以“2018”开头。我需要一个 .Match 子句来查找该行以除字符串“2018”以外的任何内容开头的行(请注意包括双引号)。找到时(这是棘手的一点) - 从有问题的行 before 行中删除换行符。换句话说,将违规行附加到它上面的行。

"2018-02-22 10:06:10,857","[7]"," ERROR","MyApp.Web.Infrastructure.ErrorResponseCommand","ErrorResponseCMD logs Controller: webinar | Action: Index",""
"2018-02-22 10:06:37,742","[11]"," INFO ","MyApp.Web.MvcApplication","Anon Session Starts with: {""FirstPage"": ""https://www.bankwebinars.com/wp-login.php"", ""QueryString"": """", ""SessionId"": ""uhnev2dnds33dastwrdgftvm"", ""FirstCookies"": {""CookieName"": ""ASP.NET_SessionId"", ""Value"": ""uhnev2dnds33dastwrdgftvm""}}",""
"2018-02-22 10:06:48,053","[11]"," INFO ","MyApp.Web.Controllers.CartController","SessionInfo{
  ""FirstPage"": null,
  ""RemoteAddress"": ""207.46.13.159"",
  ""RemoteHost"": ""207.46.13.159"",
  ""RemoteUser"": """",
RelativeConfirmPasswordResetUrl:Account/PasswordResetConfirm
//and other non-predictable BOL patterns.
},""
"2018-02-22 10:06:10,857","[7]"," ERROR","MyApp.Web.Infrastructure.ErrorResponseCommand","ErrorResponseCMD logs Controller: webinar | Action: Index",""

附录:尝试了建议的模式 - 并注意到该模式适用于 regex101 的沙箱 - 肯定还有其他问题。这是我当前的代码。

string str = File.ReadAllText("myLog.log");            
Regex rx = new Regex("(?m)\r?\n^(?!\"2018)", RegexOptions.Singleline);
str = rx.Replace(str, "\"2018");            
File.WriteAllText("test1.txt", str);

我已经尝试了一系列的模式变化 - 例如我认为 RegexOption 子句等同于 (?m) 短语,所以我尝试省略它。单行应该是我想要的,因为它将整个文件视为单行,但我也尝试过多行模式。这是一个 Windows 文件,所以 ?不需要 \r 和 \n 之间的限定符。没有任何变体改变了输出。

【问题讨论】:

  • 你的模式有什么问题?
  • 或者更好,你尝试过的模式是什么?

标签: .net regex


【解决方案1】:

您的代码按自上而下的顺序可能存在的问题

1- 我看到了File.ReadAllText()emphasizes的文档页面:

结果字符串不包含终止回车 和/或换行。

如果这是问题,请查看 this thread,我不是 .NET 专家。

2- 你需要在caring about inner double quotation mark 旁边添加@-quote 正则表达式字符串("" 表示@-quoted 字符串中的")并删除s 标志,这是额外的。

Regex rx = new Regex(@"(?m)\r?\n^(?!""2018)");

3- 接下来是您提供的替换字符串。你应该什么都不换。 Zero-Width Negative Lookahead Assertion 断言并且不消耗:

str = rx.Replace(str, ""); 

Live demo

【讨论】:

  • 所有点都正确。谢谢!对于未来的人们:问题 #1 的解决方案是 string str = File.ReadAllText("myText.txt", Encoding.ASCII);
【解决方案2】:

这是完成这项工作的正则表达式替换:

str = Regex.Replace(str, @"\r?\n(?!""2018)", String.Empty);

问题中的以下代码不正确:

Regex rx = new Regex("(?m)\r?\n^(?!\"2018)", RegexOptions.Singleline);
str = rx.Replace(str, "\"2018");

(?!\"2018) 是负前瞻。像其他外观一样,它实际上并不捕获匹配的文本。这就是为什么rx.Replace(str, "\"2018") 会导致将"2018 添加到每个移动的字符串中。例如输入:

"2018" Line 1
"2018" Line 2
  Sub-line 1
  Sub-line 2
"2018" Line 3

你会得到以下结果:

"2018" Line 1
"2018" Line 2"2018  Sub-line 1"2018  Sub-line 2
"2018" Line 3"2018

这就是为什么你应该只用一个空字符串替换匹配的部分。在这种情况下,您将得到正确的结果:

"2018" Line 1
"2018" Line 2  Sub-line 1  Sub-line 2
"2018" Line 3

【讨论】:

    【解决方案3】:

    通过执行以下操作,我能够得到我认为想要的结果:

    Regex.Replace(logString, @"\r\n\s\s", "", RegexOptions.Multiline)
    

    【讨论】:

    • 根据提供的样本的简短 sn-p 是的,您的回答就足够了。我已经编辑了 OP 以包含更多需要适应的变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多