2016-02-18 2 views
0

Я хотел бы извлечь текст в bold с поддержкой Java regex.Извлечь текст без условного lookahead в Java

я мог заставить его работать с помощью условного предпросмотр, с регулярным выражением будучи

(\d{2})(\d{1,2})(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\s+(\S+)\s+(?(?=.*\d{4}-\d{1,2}-\d{1,2})([^\d{4}]*)|(.*))

Однако Java класс шаблон не поддерживает условные lookaheads. Есть ли способ переписать регулярное выражение так, чтобы он работал с классом Java Pattern?

160203 03:24:24 mysqld_safe Запуск демона туздЫ с базами данных из/вар/Библиотека/MySQL 2016-02-03 3:24:25 0 [Внимание] TIMESTAMP с неявным значением по умолчанию является устаревшим. Используйте опцию -explicit_defaults_for_timestamp (подробнее см. Документацию) .2016-02-03 03:24:25 0 [Примечание] /opt/devenv/mysql/mysql-5.6.27-linux-glibc2.5-x86_64/ bin/mysqld (mysqld 5.6.27), начиная с процесса 29491 ... 2016-02-03 03:24:25 29491 [Примечание] Доступен IPv6.

160203 21:33:17 mysqld_safe Число процессов работает в настоящее время: 0

160203 21:33:17 mysqld_safe туздЫ перезапущен 2016-02-03 21:33:18 1125 [Примечание] Сервер hostname (bind-address): '*'; порт: 33062016-02-03 21:33:18 1125 [Примечание] Доступен IPv6.

+0

Вы должны уточнить свое правило для извлечения текста. Ex, это должно быть начало строки или sth. –

+0

Конечно, должен был упомянуть об этом. Я хочу подобрать весь текст до первого появления даты patttern, аналогичной 2016-02-03 ИЛИ до конца, если шаблон не найден. –

ответ

1

Что вы ищете является закаленным опережения:

(?:(?!\d{4}-\d{1,2}-\d{1,2}).)* 

Это соответствует всему вплоть до (но не включая) следующую вещь, которая выглядит как дата, или на следующем конце линии, что наступит первый. Это делается для проверки каждого символа до его потребления, чтобы убедиться, что это не первый символ даты. Для того, чтобы использовать это в Java:

Pattern p = Pattern.compile(
    "(?m)^(\\d{2})(\\d{1,2})(\\d{1,2})\\s+(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\\s+(\\S+)\\s+((?:(?!\\d{4}-\\d{1,2}-\\d{1,2}).)*)"); 
Matcher m = p.matcher(s); 
while (m.find()) { 
    // matched text: m.group() 
} 

(?m)^ убеждается каждый матч начинается в начале строки.

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

160203 21:33:17 mysqld_safe process1 restarted2016-02-03 21:33:18 1125 

... ваше регулярное выражение останавливается перед 1 в process1.

[^\d{4}]* в своем регулярном выражении, по-видимому хотел остановиться на следующей последовательности четыре символов, но это действительно останавливает любой символ, который не один из {, } или цифра. Конечно, только после lookahead определил, что впереди впереди дата.

+0

Спасибо Алан. Я не очень хорошо понимаю закаленные взгляды. Как использовать выражение, которое вы дали для извлечения моего текста (в BOLD)? Я попытался объединить ваше выражение с моим, что-то вроде (\ d {2}) (\ d {1,2}) (\ d {1,2}) \ s + (\ d {1,2}): (\ d {1,2}): (\ г {1,2}) \ S + (\ S +) \ S + (?:?! (\ д {4} - \ d {1,2} - \ г {1,2 }).) *. Однако он не дает мне полного текста. –

+0

Все, что соответствует регулярному выражению (полужирный текст в ваших выборках), будет в группе (0). Я добавил код для демонстрации ('group()' и 'group (0)' эквивалентны). –

+0

Хорошо, теперь я вижу. Тем не менее, я бы идеально хотел захватить несколько групп. У меня уже есть 7 групп захвата перед этим закаленным взглядом. Какой бы текст не появлялся после этого (uptil date pattern OR end of string) должен быть захвачен как группа 8. В любом случае это может быть выполнено? –

Смежные вопросы