2016-02-18 15 views
0

我想使用Java正则表达式支持提取黑体中的文本。在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 Pattern类不支持有条件的向前看符号。有没有办法重写正则表达式,以便它可以与Java模式类一起使用?与来自的/ var/lib中/ MySQL的 2016年2月3日3点24分25秒0 [警告]时间戳和隐含默认值数据库

160203三时24分24秒开始mysqld_safe的mysqld守护被弃用。请使用--explicit_defaults_for_timestamp服务器选项(详情请参阅文档).2016-02-03 03:24:25 0 [Note] /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的重新启动mysqld的 2016年2月3日21点33分18秒1125 [注]服务器主机名(bind-address):'*';端口:33062016-02-03 21:33:18 1125 [注] IPv6可用。

+0

你应该澄清你的规则来提取文本。例如,它必须是行的开始或某事。 –

+0

当然,应该提到这一点。我想拾取所有文本,直到第一次出现类似于2016-02-03的日期patttern,或者如果未找到该模式,则直到结束。 –

回答

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 

...您正则表达式中process11之前停止。

在你的正则表达式的[^\d{4}]*显然是停下来的意思,在接下来的四个字符序列,但它确实停止,这不是的{一个,},或任意字符。当然,只有之后的超前才确定有未来的日期。

+0

谢谢艾伦。我对锻炼的lookaheads没有太多的想法。我应该如何使用你给出的表达式来提取我的文本(BOLD)? (\ d {1,2})(\ d {1,2})\ s +(\ d {1,2}):(\ d {1,2}) {1,2}):(\ d {1,2})\ S +(\ S +)\ S +(:?!(\ d {4} - \ d {1,2} - \ d {1,2 }))*。但是,它并没有给我全文。 –

+0

正则表达式匹配的所有内容(样本中的粗体文本)都将位于组(0)中。我已经添加了一些代码来演示('group()'和'group(0)'是等价的)。 –

+0

好吧,我明白了。但是,我最好想要捕获多个组。在这个温文尔雅的回顾之前,我已经有了7个捕捉组。无论出现哪种文本(直到日期模式或字符串结尾)都应该被捕获为第8组。无论如何,这可以完成? –