Java Regex:使用边界条件匹配两个字符串之间的文本

时间:2013-04-28 00:23:50

标签: java regex parsing match

我想匹配两个字符串之间的文本,但起始字符串具有严格的边界条件。

示例输入:

start
From: h
From:b
 xyz
Subject: 
end

我需要在From:Subject:之间进行匹配。

如果我将(From:.*).*(Subject:)与dotall一起使用,则会生成

From: h
From:b
 xyz
Subject:

但我只需要

From:b
 xyz
Subject:

因为起始字符串具有严格的边界条件。这是必要的,因为起始字符串可以在文档中的任何位置,然后上面的正则表达式将匹配大文本而不是几行。

%%%%%%%%%%%%问题已重新定义%%%%%%%%%%%%%%% 我有需要匹配的文字:

From:<any text>
To:<any text>
Subject:<any text>

问题在于:所有三个组件可以在一行中,可以用一个换行符分隔,或者可以用2个换行符分隔...在所需匹配之前和之后有文本可以包含{{1这就是为什么我需要严格的界限。

4 个答案:

答案 0 :(得分:2)

试试这个:

String input = "start From: h From:b xyz Subject: end";
Matcher matcher = Pattern.compile("(?<=^((?!From:).)*(From: [A-Za-z0-9] ))(.+?)(Subject:)").matcher(input);
if (matcher.find())
{
    System.out.println(matcher.group());
}

输出:From:b xyz Subject:


正则表达式((?<=^((?!From:).)*(From: [A-Za-z0-9] ))(.+?)(Subject:))的说明:

  • (?<=开始关注
  • ^字符串的开头
  • ((?!From:).)如果向前看,你看不到“从:”然后匹配任何角色
  • *匹配前一个语句零次或多次
  • (From: [A-Za-z0-9] ))匹配第一个“发件人:”及其内容
  • )停止向后看
  • (.+?)匹配我们正在寻找的字符串
  • (Subject:)匹配主题字段

答案 1 :(得分:0)

我建议你不要在DOTALL模式下使用.*,而是建议你一次匹配一行,断言该行不以From:开头。

"(?m)^From:.*[\r\n]+(?:(?!From:).*[\r\n]+)*Subject:.*$"

这是最低限度的实施。根据文本的结构,它仍然可能匹配太多或太慢(特别是在无法匹配的情况下)。这是一个更强大的版本:

"(?m)^(?>From:.*[\r\n]+)(?>(?!From:|Subject:).*[\r\n]+)*+Subject:.*$"

答案 2 :(得分:0)

使用多线修改器和否定前瞻:

(?s)From:((?!From:).)*?Subject: @ regex101

注意:regex101小提琴包含实时正则表达式和测试数据。

答案 3 :(得分:0)

简单地说:

From\:\w*(?!From\:\w*)\n*\w*\n*Subject:\w*

演示:https://regex101.com/r/mX9kC7/3