我有一个与此非常相似的文本提要文件:
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/