Java Regex使用DOTALL捕获任何(。*)忽略零宽度正向前瞻

时间:2012-01-27 14:17:04

标签: java regex

不是正则表达式专家,但我知道这很危险,需要一些我正在研究的表达方面的帮助。简而言之,最近的数据库升级使我支持的遗留应用程序的字符串文字中的数千个查询无效。我正在编写一些表达式来捕获其中的大多数,并希望以编程方式修复它们。

请考虑以下事项:

Query query = session
                .createSQLQuery("SELECT distinct p.userid, p.name, f.hsid, "
                        + "p.vid, p.vname, p.paymentdate, p.amount "
                        + "FROM vk.payment p, (select * from vs.fuser) fu, (select * from vs.fac) f "
                        + "WHERE  p.description = 'Check' AND "
                        + "p.paymentdate >= :startDate and p.paymentdate <= :endDate AND "
                        + "fu.userid = p.userid AND fu.facid = f.facid "
                        + "ORDER BY p.userid");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);

我有以下DOTALL表达式来尝试和捕获方法参数的丑陋内容。

(?s)(?<=\.createSQLQuery\(")(.*)(?="\)\;)

我指定带有(?s)的DOTALL标志,后面是非捕获外观以获取\.createSQLQuery\(",捕获所有内容,包括使用(.*)的换行符,最后是非捕获正向前瞻以停止捕获"\)\;

我期待抓住以下内容:

SELECT distinct p.userid, p.name, f.hsid, "
                            + "p.vid, p.vname, p.paymentdate, p.amount "
                            + "FROM vk.payment p, (select * from vs.fuser) fu, (select * from vs.fac) f "
                            + "WHERE  p.description = 'Check' AND "
                            + "p.paymentdate >= :startDate and p.paymentdate <= :endDate AND "
                            + "fu.userid = p.userid AND fu.facid = f.facid "
                            + "ORDER BY p.userid

相反,表达式比我预期的要贪得多,并且正在抓住这个:

SELECT distinct p.userid, p.name, f.hsid, "
                            + "p.vid, p.vname, p.paymentdate, p.amount "
                            + "FROM vk.payment p, (select * from vs.fuser) fu, (select * from vs.fac) f "
                            + "WHERE  p.description = 'Check' AND "
                            + "p.paymentdate >= :startDate and p.paymentdate <= :endDate AND "
                            + "fu.userid = p.userid AND fu.facid = f.facid "
                            + "ORDER BY p.userid");
            query.setParameter("startDate", startDate);
            query.setParameter("endDate", endDate);
               ... to EOF

问题在于,如果没有DOTALL,表达式就会按预期在一行上运行:

Query query = session.createSQLQuery("SELECT .... ");

并且在没有剩下的字符的情况下捕获...

SELECT .... 

DOTALL的某些方面是否每个正则表达式大师似乎都知道似乎没有记录在任何地方? DOTALL不能用积极的前瞻工作吗?

我感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

通过在*之后添加?来使.*?量词非贪婪,如下所示:(?s)\.createSQLQuery\("(.*?)"\);

为什么你甚至使用lookarounds?在某些情况下,它可能会导致意外行为,而不必像这样使用它们。 (它总是让我感到烦恼。( - ;)

你可以使用:

{{1}}