.net - 文本提要的正则表达式替换

标签 .net regex

我有一个与此非常相似的文本提要文件:

F00020000100008252011
H123400010000050008201975
D23451234567891234567800000000000000000000000000000500
D23461234567891234567800000000000000000000000000000500
H789100010000050008201975
D54321234567891234567800000000000000000000000000000500
D54331234567891234567800000000000000000000000000000500

...其中以F开头的行是文件头,以H开头的行是批处理头,以D开头的行是详细记录。我想运行正则表达式替换表达式(.NET),其中我的结果将是文件头、特定批处理头以及该特定批处理头下的所有详细记录(没有其他)。这看起来相当简单,但事实证明它比我预期的要困难,就像我开始搞乱正则表达式时的情况一样。我在 C# 中使用 MultiLine Regex 对象。我可以为正则表达式字符串和替换字符串提供什么来生成下面的结果?

F00020000100008252011
H123400010000050008201975
D23451234567891234567800000000000000000000000000000500
D23461234567891234567800000000000000000000000000000500

F00020000100008252011
H789100010000050008201975
D54321234567891234567800000000000000000000000000000500
D54331234567891234567800000000000000000000000000000500

注意:

虽然此应用程序是内部开发的,并且可以进行更改以以更优雅的方式支持此应用程序,但这将需要代码更改、单元测试、质量保证和变更控制流程,这将严重延迟此应用程序的可用性喂养。如果可能的话,我想使用内置的正则表达式替换机制,这样就不需要为此任务投入额外的资源。

我尝试过以下方法:

正则表达式:

(?<fileheader>^F.*$)|(?<batchheader>^H1234.*$)|(^H1234.*$(?<detail>^D\d*$))

替换:

${fileheader}${batchheader}${detail}

无法找到所有详细信息

正则表达式:

(?<fileheader>^F.*$)|(?<batchheader>^H1234*.$)|(?<detail>^D.*$)

替换:

${fileheader}${batchheader}${detail}

并获取所有详细信息,甚至是不在批处理中的详细信息。

正则表达式:

(?<fileheader>^F.*$)|(?<batchheader>^H1234*.$)|^H1234*.$^[D0-9]*$(?<detail>^D.*$)

替换:

${fileheader}${batchheader}${detail}

只找到文件头。

正则表达式:

(?<FileHeader>F\d+\r\n)(?<UnWanted>(?!H1234)[HD]\d*[\r\n]*)*(?<BatchHeader>H1234\d*\r\n)(?<Detail>D\d*[\r\n]*)*(?<UnWanted2>(?!H1234)[HD]\d*[\r\n]*)*

替换:

${FileHeader}${BatchHeader}${Detail}

这让我几乎得到了我需要的东西,但只有一个详细记录。

...以及类似的许多变体。

最佳答案

使用这样的方法可能会更好地解决您的问题。

尝试读取文件的每一行,而不是使用 MultiLineRegex。这很简单 足够不需要这样的措施,因为每行应该仅以 F、H 或 D 开头。

读取以 F 开头的行后,下一行应以 H 或 F 开头(在 System.String 中使用 StartsWith)。

  • 如果下一行以 H 开头,则我们有第一个批处理 header 。
  • 如果下一行以 F 开头,则我们有下一个文件头(没有批处理头)。

读完以 H 开头的一行后,下一行应以 D、H 或 F 开头。

  • 如果下一行以 D 开头,则我们有第一个详细记录。
  • 如果下一行以 H 开头,则我们有下一个批处理 header 。
  • 如果下一行以 F 开头,则我们有下一个文件头(不再有批处理头)。

读完以 D 开头的行后,下一行应以 D、H 或 F 开头。

  • 如果下一行以 D 开头,则我们有下一条详细记录。
  • 如果下一行以 H 开头,则我们有下一个批头(没有更多详细记录)。
  • 如果下一行以 F 开头,则我们有下一个文件头(没有更多详细记录)。

该算法的工作原理与状态机类似。

关于.net - 文本提要的正则表达式替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7180508/

相关文章:

javascript - 规避asp事件处理程序

c# - 带有 IFormattable 参数的函数不接受字符串

regex - 如何用 Perl 替换文件中的特定 IP?

regex - 正则表达式匹配非零、零填充的整数

javascript - 拆分正则表达式数字

.net - .net 注释应该以大写字母开头并以句点结尾吗?

c# - 是否将用户设置存储在 ASP.NET Core Identity AspNetUsers 表中

c# - ClickOnce 发送参数不起作用

java - intellij IDEA中如何打开或调用regexTester插件

javascript - 正则表达式测试,但仅当 11 个字符时