Java Regex перехватывает любые (. *) С помощью DOTALL, игнорируя позитивный прогноз нулевой ширины - PullRequest
1 голос
/ 27 января 2012

Не эксперт по регулярным выражениям, но я знаю достаточно, чтобы быть опасным, нужна помощь с выражением, над которым я работаю. Короче говоря, недавнее обновление базы данных сделало недействительными тысячи запросов в строковых литералах унаследованного приложения, которое я поддерживаю. Я пишу несколько выражений, чтобы охватить большинство из них и, надеюсь, исправить их программно.

Обратите внимание на следующее:

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\(")(.*)(?="\)\;)

Я указываю флаг DOTALL с (?s) для не захватывающего просмотра, чтобы получить \.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 Ответ

3 голосов
/ 27 января 2012

Сделайте квантификатор * нежадным, добавив после него ?, например: .*?

Кроме того, почему вы даже используете lookarounds? В некоторых случаях это может привести к нежелательному поведению, если вы будете использовать их без такой мысли. (И это меня всегда раздражает. (-;)

Вы можете просто использовать:

(?s)\.createSQLQuery\("(.*?)"\);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...