首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用正则表达式提取不同的文本块和多行?

是否可以使用正则表达式提取不同的文本块和多行?
EN

Stack Overflow用户
提问于 2014-04-29 15:04:37
回答 1查看 574关注 0票数 1

我想使用正则表达式从报表文档中提取不同的文本块--每个新页面在下面没有显示的“第一个通知”前面用\x0c表示。我已经包括了图片w/行号以及文本,尽管格式化可能是一个问题。

报告文本将包含1..n页--在返回数据时,每个页面都是一个单独的行项。该数据将被提取并转换为行,然后输入数据库号、余额、名称、Address1、Address2、城市、州、Zip。

我需要提取的数据片段:

  1. 编号- 11-1-11111-1
  2. 余额- 1000.00
  3. 名称- "DOEN,JOHN THOMAS“行14,col 7-50
  4. 地址-2至3行
  5. 进一步-进入Addr1/Addr2/City/State/Zip
  6. 与城市的界线:城市ST Zip4或Zip-9
  7. 城市可以容纳空间

数字和余额是相对容易获得-这是名称和地址部分,我有最大的问题,并正在寻找一个单一的正则表达式,将把每个项目纳入自己的小组。

地址在第15-17行和第7-50栏.

这有可能吗?

包含两页的示例文档:

代码语言:javascript
复制
 FIRST NOTICE                         COMPANYNAME
 NOTICE DATE....: 01/01/2001          1111 N NORTHWOOD DR
 NUMBER.........: 11-1-11111-1        SOMEWHERE WY 05920-5929
 THE DATE.......: 02/01/2001

 Some data only.







      DOEN, JOHN THOMAS                           ORIGINAL....:      5789.00
      1111 N WALT AVE                             BALANCE.....:      1000.00
      C/O SOMEONE ELSE                            PAST DUE....:       500.00
      SOMEWHERE WY 04741-5555

 THIS IS THE END OF THIS PAGE                     DATE DUE: 02/01/2001
 FIRST NOTICE                         COMPANYNAME
 NOTICE DATE....: 01/01/2001          1111 N NORTHWOOD DR
 NUMBER.........: 22-2-22222-2        SOMEWHERE WY 05920-5929
 THE DATE.......: 02/01/2001

 Some data only.







      DOE, JOHNAT ZOAR                            ORIGINAL....:      2211.00
      11111 N DIVISOR RD                          BALANCE.....:      2000.00
      SOMWEHERE WY 05922                          PAST DUE....:      1000.00


 THIS IS THE END OF THIS PAGE                     DATE DUE: 02/01/2001
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-29 15:10:01

Regex显式支持多行,如下所示

代码语言:javascript
复制
Regex reg = new Regex(@"pattern1|pattern2", RegexOptions.Multiline);
var matches = reg.Matches("my text with /n lines");

Regex的另一个方面是,您可以将模式划分为段,这相当于要匹配的替代文本。请参阅竖直杆上的这篇文章。使用从MatchCollection返回的reg.Matches,您将能够提取数据。

我建议分别在名称和地址行上进行匹配,例如,如果您总是可以依赖与名称相同的行上的字符串原始位置,那么您可以分别为其编写regex。regex引擎将按照顺序匹配模式,但您需要一些锚文本来搜索清楚,然后获得相对于锚文本的值。然后,您需要解析并清除Match对象中返回的值。

更新我以前的答案被部分编辑以删除无关的信息

下面是一个包含解决方案的程序,Regex相对简单,所以我将对那些不熟悉第一种模式的语法的人进行细分:

代码语言:javascript
复制
^[A-Z, ]+(?=original...)|^[A-Z, 0-9]+(?=balance...)|^[//A-Z, 0-9]+(?=past due...)|^[^\n\.]{2,50}(?=\n\s+\n^\s+THIS IS THE END OF THIS PAGE)  

regex包含4种单独的模式,由|拆分,这意味着交互。

您可以测试模式http://regexstorm.net/tester,小心不要添加任何额外的字符,并确保检查多行和忽略大小写选项。

^通过Regex构造函数捕获行的开始,因为我们正在使用多行模式。

[A-Z, ]捕获and、逗号和空格

+重复前面令牌1或更多次的重复出现,相当于表示{1,}

(?=original....)对这种模式的展望--在本例中--original....因此(?=pattern)

前瞻不捕获字符,但只捕获匹配字符。

其他模式相似,尽管最后一个模式匹配锚点之前的几行空白行,这是这个页面的末尾,并在一些字符{2,50}上设置了一个min/max

C#示例,它为示例数据清除返回的令牌-名称和地址-7项。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace RegexTester
{
    class Program
    {
        static string text = @"FIRST NOTICE                         COMPANYNAME
 NOTICE DATE....: 01/01/2001          1111 N NORTHWOOD DR
 NUMBER.........: 11-1-11111-1        SOMEWHERE WY 05920-5929
 THE DATE.......: 02/01/2001

 Some data only.







      DOEN, JOHN THOMAS                           ORIGINAL....:      5789.00
      1111 N WALT AVE                             BALANCE.....:      1000.00
      C/O SOMEONE ELSE                            PAST DUE....:       500.00
      SOMEWHERE WY 04741-5555

 THIS IS THE END OF THIS PAGE                     DATE DUE: 02/01/2001
 FIRST NOTICE                         COMPANYNAME
 NOTICE DATE....: 01/01/2001          1111 N NORTHWOOD DR
 NUMBER.........: 22-2-22222-2        SOMEWHERE WY 05920-5929
 THE DATE.......: 02/01/2001

 Some data only.







      DOE, JOHNAT ZOAR                            ORIGINAL....:      2211.00
      11111 N DIVISOR RD                          BALANCE.....:      2000.00
      SOMWEHERE WY 05922                          PAST DUE....:      1000.00


 THIS IS THE END OF THIS PAGE                     DATE DUE: 02/01/2001";

        static void Main(string[] args)
        {
            string pattern = @"^[A-Z, ]+(?=original...)|^[A-Z, 0-9]+(?=balance...)|^[//A-Z, 0-9]+(?=past due...)|^[^\n\.]{2,50}(?=\n\s+\n^\s+THIS IS THE END OF THIS PAGE)";
            Regex regex = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
            MatchCollection matches = regex.Matches(text);
            List<string> cleaned = matches.Cast<Match>().Select(x => x.Value.Trim()).ToList();
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23368437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档