我想使用正则表达式从报表文档中提取不同的文本块--每个新页面在下面没有显示的“第一个通知”前面用\x0c表示。我已经包括了图片w/行号以及文本,尽管格式化可能是一个问题。
报告文本将包含1..n页--在返回数据时,每个页面都是一个单独的行项。该数据将被提取并转换为行,然后输入数据库号、余额、名称、Address1、Address2、城市、州、Zip。
我需要提取的数据片段:
数字和余额是相对容易获得-这是名称和地址部分,我有最大的问题,并正在寻找一个单一的正则表达式,将把每个项目纳入自己的小组。
地址在第15-17行和第7-50栏.
这有可能吗?
包含两页的示例文档:

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发布于 2014-04-29 15:10:01
Regex显式支持多行,如下所示
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相对简单,所以我将对那些不熟悉第一种模式的语法的人进行细分:
^[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项。
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();
}
}
}https://stackoverflow.com/questions/23368437
复制相似问题