首页 > 解决方案 > 如何处理正则表达式中的冗余案例?

问题描述

我必须将文件数据解析为好记录和坏记录,数据应该是格式

Patient_id::Patient_name (year of birth)::disease

疾病是管道分离的并且选自以下:

1.HIV
2.Cancer
3.Flu
4.Arthritis 
5.OCD

示例:23::Alex.jr (1969)::HIV|癌症|流感

我写的正则表达式是

\d*::[a-zA-Z]+[^\(]*\(\d{4}\)::(HIV|Cancer|flu|Arthritis|OCD) 
     (\|(HIV|Cancer|flu|Arthritis|OCD))*

但它也在考虑具有冗余条目的记录

24::罗宾 (1980)::HIV|癌症|癌症|HIV

如果疾病列表非常大,如何处理这些记录以及如何编写更好的表达方式。

注意:我正在使用 hadoop maponly 作业进行解析,因此请在 java 的上下文中给出答案。

标签: regexparsingmapreducehadoop2

解决方案


您可能要做的是将所有疾病的最后一部分捕获在一个组中(命名为捕获组disease),然后使用 split 来获取单个疾病,然后使列表唯一。

^\d*::[a-zA-Z]+[^\(]*\(\d{4}\)::(?<disease>(?:HIV|Cancer|flu|Arthritis|OCD)(?:\|(?:HIV|Cancer|flu|Arthritis|OCD))*)$

例如:

String regex = "^\\d*::[a-zA-Z]+[^\\(]*\\(\\d{4}\\)::(?<disease>(?:HIV|Cancer|flu|Arthritis|OCD)(?:\\|(?:HIV|Cancer|flu|Arthritis|OCD))*)$";
String string = "24::Robin (1980)::HIV|Cancer|Cancer|HIV";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);

if (matcher.find()) {
    String[] parts =  matcher.group("disease").split("\\|");
    Set<String> uniqueDiseases = new HashSet<String>(Arrays.asList(parts));
    System.out.println(uniqueDiseases);
}

结果:

[HIV, Cancer]

正则表达式演示| Java 演示


推荐阅读