我想使用正则表达式从报表文档中提取不同的文本块 - 每个新页面在"第一通知"前面用\ x0c表示。 [未在下面显示]。虽然格式化可能是一个问题,但我已经包含了带行号和文本的图片。
报告文本将包含1..n页 - 每次返回数据时都是一个单独的行项。此数据将被提取并转换为行,以输入数据库[数字,余额,名称,地址1,地址2,城市,州,邮编]。
我需要提取的数据:
数量和余额相对容易获得 - 它是我遇到最多问题的名称和地址部分,我正在寻找一个将每个项目拉到自己的组中的正则表达式。
地址在第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
答案 0 :(得分:2)
正则表达式明确支持多行,如下所示
Regex reg = new Regex(@"pattern1|pattern2", RegexOptions.Multiline);
var matches = reg.Matches("my text with /n lines");
正则表达式的另一个方面是,您可以将模式划分为多个段,这些段相当于要匹配的备用文本。请参阅vertical bar上的这篇文章。使用reg.Matches返回的MatchCollection,您将能够提取数据。
我建议单独匹配名称和地址行,如果你总是可以依赖字符串ORIGINAL位于与名称相同的行的右边,那么你可以单独编写正则表达式。正则表达式引擎将按顺序匹配模式,但您需要一些锚文本来清楚地搜索,然后获取相对于锚文本的值。然后,您需要解析并清理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)
正则表达式包含由|
分割的4个单独模式,这意味着交替。
您可以测试模式here,注意不要添加任何额外字符,并确保检查多行并忽略大小写选项。
^
捕获行的开头,因为我们通过Regex构造函数使用多行模式
[A-Z, ]
捕获A-Z,逗号和空格
+
重复出现前一个令牌1次或更多次,相当于说{1,}
(?=original....)
预测此案例中的模式original....
因此(?= 模式)
The lookahead不会捕获字符,只会匹配。
其他模式是相似的,尽管最后一个模式匹配锚点之前的几个空白行。这是此页面的结尾并设置某些字符的最小/最大出现次数{2,50}
C#sample清除返回的标记 - 名称和地址 - 示例数据的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();
}
}
}