使用regex从文本中删除整行,忽略重复部分,只根据条件留下行

本文关键字:复部 条件 文本 regex 删除 使用 | 更新日期: 2023-09-27 18:06:23

我一直致力于一个项目,将c#中的文本文件操作成可用的东西,我可以将其作为CSV拉入excel中。几周前我问了另一个问题,这是朝着正确方向迈出的明确的一步,但是我有一些额外的限制,我想弄清楚。

链接到上一个问题的背景:原问题

输入文本文件(下面是一个示例)具有与存储在数据库中的文档相关联的几种类型的数据。每个文档的数据被分成几个部分,用"BEGIN:"表示。原来的正则表达式删除了大部分的换行符,删除了数据标签,以及我选择删除的标记为"Ad Hoc"的行,因为它不存在于每个文件中,所以当我将它带入excel时,它会对列不对齐。

在查看了这个数据库输出的其他文本文件后,我发现有更多的不一致,所以因为我真的只需要2或3个数据,我认为除了需要的东西之外,删除所有东西是最容易的。

我尝试使用管道(我已经理解为regex中的"或"操作符)来尝试向表达式添加额外的条件,但是一旦我添加了多个额外条件,它就会开始跳过下面的条件。

以下是我的要求,下面我将粘贴示例文本:

  1. 我只需要每个文档部分的2个数据项:文档句柄和文件名。
  2. 在文本文件的底部有一个文件路径的附加部分,用"'"表示
  3. 在某些文本文件中,filename和底部的路径是重复的,但都是相同的

文本文件是我们正在使用的文档数据库的输出,因为它是相当无用的。我的目标是能够把一些东西拉到excel中,它有每个文档的文档句柄和文件名(以"BEGIN:"开头的每个部分是一个单独的文档),并在底部有完整的文件路径。到目前为止,我一直使用分号来分隔文本时,将其拉入excel。

示例文本:

>>>>Self Configuring Tagged DIP<<<<
BEGIN:
>>DocTypeName: System Maintenance Forms
>>DocDate: 3/18/2013
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Document Handle: 599954
>>DiskgroupNum: 102
>>VolumeNum: 110
>>NumOfPages: 0
>>FileSize: 303909
>>DocRevNum: 0
>>Rendition: 1
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 16
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V110'1366'798567.pdf
BEGIN:
>>DocTypeName: Post Closing Contact Sheet
>>DocDate: 3/18/2013
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample 
City: DECATUR
State: GA
Ad Hoc: 2013 02 26 BWR CONTACT INFO UPDATE FOORM
Document Handle: 599983
>>DiskgroupNum: 102
>>VolumeNum: 110
>>NumOfPages: 0
>>FileSize: 276653
>>DocRevNum: 0
>>Rendition: 1
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 16
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V110'1366'798596.pdf
BEGIN:
>>DocTypeName: Insurance ACORD
>>DocDate: 1/11/2008
Policy Number: 91QB94439
Effective Date: 01/24/2008
Expiration Date: 01/24/2009
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: 3642 sample
City: DECATUR
State: GA
Document Handle: 98326
>>DiskgroupNum: 102
>>VolumeNum: 24
>>NumOfPages: 1
>>FileSize: 74839
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V24'202'133225.TIF
>>DiskgroupNum: 102
>>VolumeNum: 24
>>NumOfPages: 1
>>FileSize: 74839
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 1
>>ItemPageNum: 1
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V24'202'133225.TIF
BEGIN:
>>DocTypeName: Insurance ACORD
>>DocDate: 1/2/2008
Policy Number: 91QB94439
Effective Date: 01/24/2008
Expiration Date: 01/24/2009
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Document Handle: 94202
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 78846
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'194'128851.TIF
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 78846
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 1
>>ItemPageNum: 1
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'194'128851.TIF
BEGIN:
>>DocTypeName: Insurance ACORD
>>DocDate: 12/6/2007
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Document Handle: 89402
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 126946
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'184'123535.TIF
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 126946
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 1
>>ItemPageNum: 1
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'184'123535.TIF
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 126946
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 2
>>ItemPageNum: 2
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'184'123535.TIF
>>DiskgroupNum: 102
>>VolumeNum: 23
>>NumOfPages: 1
>>FileSize: 126946
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 3
>>ItemPageNum: 3
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V23'184'123535.TIF
BEGIN:
>>DocTypeName: Insurance ACORD
>>DocDate: 4/11/2007
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Document Handle: 24385
>>DiskgroupNum: 102
>>VolumeNum: 5
>>NumOfPages: 1
>>FileSize: 64763
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V5'47'35166.TIF
BEGIN:
>>DocTypeName: Insurance ACORD
>>DocDate: 2/7/2007
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Document Handle: 6272
>>DiskgroupNum: 102
>>VolumeNum: 1
>>NumOfPages: 1
>>FileSize: 135355
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V1'10'7921.TIF
>>DiskgroupNum: 102
>>VolumeNum: 1
>>NumOfPages: 1
>>FileSize: 135355
>>DocRevNum: 0
>>Rendition: 0
>>PhysicalPageNum: 1
>>ItemPageNum: 1
>>FileTypeNum: 2
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V1'10'7921.TIF
BEGIN:
>>DocTypeName: Assignment of Leases and Rents
>>DocDate: 10/18/2012
Loan Number: 893102103
Property Name: sample
Borrower Name: sample
Address: sample
City: DECATUR
State: GA
Ad Hoc: LOAN ASSUMPTION
Document Handle: 562703
>>DiskgroupNum: 102
>>VolumeNum: 102
>>NumOfPages: 0
>>FileSize: 623209
>>DocRevNum: 0
>>Rendition: 1
>>PhysicalPageNum: 0
>>ItemPageNum: 0
>>FileTypeNum: 16
>>ImageType: 0
>>Compress: 2
>>Xdpi: 0
>>Ydpi: 0
>>FileName: 'V102'1300'760684.pdf
END:
InstallID: Laureate
Volume: 102,1,3997815,Loan Administration,''gbcdconbase01'D'DiskGroups'loan_admin,
Volume: 102,5,3999736,Loan Administration,''gbcdconbase01'D'DiskGroups'loan_admin,
Volume: 102,6,3998253,Loan Administration,''gbcdconbase01'D'DiskGroups'loan_admin,
Volume: 102,23,3999424,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,24,3998776,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,25,3985430,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,37,3999939,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,39,3999150,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,40,3999837,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,41,3999844,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,52,3999578,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,71,3998227,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,88,3992838,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,102,3999346,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,106,3999163,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,109,3999950,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,110,3996896,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,111,3999421,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,355,3998185,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Volume: 102,358,3971185,Loan Administration,''gbcdconbase01'D'DiskGroups'LOAN_ADMIN,
Doc Count: 30

期望的最终结果是:

599954;'V110'1366'798567.pdf
599983;'V110'1366'798596.pdf
98326;'V24'202'133225.TIF
94202;'V23'194'128851.TIF
89402;'V23'184'123535.TIF
24385;'V5'47'35166.TIF
6272;'V1'10'7921.TIF
562703;'V102'1300'760684.pdf
''gbcdconbase01'D'DiskGroups'loan_admin

这是我上一个问题的原始正则表达式模式,它与顺序中的其他两个模式一起删除了换行符,数据标题和"特别"行,这可能会有所帮助。这就是我尝试在下面模式的"ad hoc"部分附近用管道从其他行添加标题的地方。

((['r'n]+'s*Ad'sHoc:.*?['r'n]+)|(['r'n]+(?!'s*BEGIN))).*?:'s*

提前感谢您的时间。

使用regex从文本中删除整行,忽略重复部分,只根据条件留下行

对于这些需求,不推荐使用正则表达式。也许有可能制作一个Regex的组合来完成这个任务,但是创建和维护这样的东西将是非常痛苦的。对于您想要做的事情,坚持使用简单的字符串操作要容易得多(这也将导致更好的可读性和可维护性代码)。

一般来说,你的代码应该这样做:
  1. 逐行读取源文件,并将每行拆分为标识符(第一个冒号之前的文本)和(第一个":"之后的文本)。将感兴趣的信息存储在一些变量中,如果需要处理的数据字段不止几个,则存储在字典中。(由于您现在只想处理"Document handle "answers"FileName"字段,因此使用两个字符串变量就可以了。)

    每当代码遇到"BEGIN"标识符时,它就以分号分隔的文本行形式将这些变量(或字典)的内容写入目标文件。这样做之后,清除变量(或字典)的值。如果这些变量为空(例如遇到第一个"BEGIN"),当然不需要向目标文件写入任何内容。

  2. 如果代码遇到"END"标识符,则让另一个循环读取剩余的源文件行,该循环以某种不同的方式处理这些行。现在,只处理带有"Volume"标识符的行,其他行将被忽略。为了避免输出重复的卷路径,将使用HashSet<string>来跟踪已经输出的卷路径。HashSet需要用StringComparer初始化。InvariantCultureIgnoreCase比较器,因为您似乎以不区分大小写的方式处理路径。

    从标识符为"Volume"的行(一个简单的字符串)的值字符串中提取路径。Split似乎可以很好地完成这项工作,但为了确保这一点,您可能需要查看特定的输入文件格式如何编码包含逗号的文本值,并检查路径是否已经存储在HashSet中。如果是,则忽略路径并继续源文件的下一行。

    如果路径尚未在HashSet中,则输出该路径并将其添加到HashSet中,然后继续执行源文件的下一行。

这差不多是你所有的代码都要做的。不要仅仅因为……而坚持使用正则表达式。您努力使现有正则表达式适应稍微改变的场景的经历是一个很好的例子,说明为什么试图用几个庞大的正则表达式来做所有事情并不能真正使任何人的生活更轻松(除非您喜欢挑战;))。此外,您可能会稍微考虑一下,与每当应用程序场景或输入文件再次发生轻微变化时创建另一个大型正则表达式相比,您(或其他开发人员)调整传统代码(如上面大致概述的代码)是多么容易……

使用这种模式是最接近您所寻找的(在底线有一个额外的分号)

.*?Document'sHandle:'s*('d+).*?>>FileName:'s*('V+)|.*Loan'sAdministration,([^,]+).*
gs改性剂
代替w/$1;$2$3'n或者也许替换w/$3$1;$2'n,然后删除最后一个字符。演示