削减激进的懒惰通配符

时间:2015-04-16 05:27:47

标签: java regex xml wildcard

我有几个模式可以解析一个简单的文本文件以获取信息,并使用数据构建一个员工对象。有两种类型的员工:全职和每小时。我倾向于使用Lazy Wildcards来解析XML数据。我的主要问题是懒惰的通配符比预期更具攻击性。全时付费记录模式(patternPRF)懒惰通配符从小时payRecord(在2)开始,然后取出所有内容,直到它在下一个payRecord中命中。无论如何,我可以统治通配符并说“你已经走得太远了”#39;或者某些东西限制给具有所有全职属性的员工(monthlyIncome& month tages而不是payHours& payRate)?

要解析的文本文件:

<payRecord id="10">
    <EmployeeID>2</EmployeeID> //matcher.group(2) starts here
    <PayHours>30</PayHours>
    <PayRate>15</PayRate>
</payRecord>
<payRecord id="11">
    <EmployeeID>1</EmployeeID>
    <MonthlyIncome>3500</MonthlyIncome> //ends here
    <NumMonths>8</NumMonths>
</payRecord>
<payRecord id="12">
    <EmployeeID>3
    </EmployeeeID>
    <MonthlyIncome>5000</MonthlyIncome>
    <NumMonths>6</NumMonths>
</payRecord>

正则表达式:

text = text.replaceAll("\\s", ""); //remove all whitespace     

//payrecord hourly
patternPRH = Pattern.compile(
        "<payRecordid=\"(.*?)\">" //1 id
                + "<EmployeeID>(.*?)</EmployeeID>" //2 EmpID
                + "<PayHours>(.*?)</PayHours>" //3 payHours
                + "<PayRate>(.*?)</PayRate>" //4 payRate
);
//payrecord fulltime
patternPRF = Pattern.compile(
        "<payRecordid=\"(.*?)\">"//1 id 
                + "<EmployeeID>(.*?)</EmployeeID>"//2 EmployeeID <EmployeeID>2</EmployeeID>
                + "<MonthlyIncome>(.*?)</MonthlyIncome>"//3 MonthlyIncome
                + "<NumMonths>(.*?)</NumMonths>"//4 numMonths
);

作为旁注,遗憾的是,作为课程要求的一部分,我无法使用任何XML解析类。

2 个答案:

答案 0 :(得分:0)

我喜欢负面的正则表达式。例如,[^"]*将匹配不是引号的字符数。

考虑使用以下内容:

patternPRH = Pattern.compile(
    "<payRecordid=\"([^\"]*)\">" //1 id
    + "<EmployeeID>([^<]*)</EmployeeID>" //2 EmpID
    + "<PayHours>([^<]*)</PayHours>" //3 payHours
    + "<PayRate>([^<]*)</PayRate>" //4 payRate
);

答案 1 :(得分:0)

为避免这种情况,您可以将匹配限制为

(\d+)

而不是

(.*?)

表示payRecordId,EmployeeID。

这样做,匹配组除了数字之外不会采取任何操作,并使你的正则表达式工作正常,除了