我必须解析多行字符串并检索特定位置的电子邮件地址。
我使用以下代码完成了它:
String input = "Content-Type: application/ms-tnef; name=\"winmail.dat\"\r\n"
+ "Content-Transfer-Encoding: binary\r\n" + "From: ABC aa DDD <aaaa.b@abc.com>\r\n"
+ "To: DDDDD dd <sssss.r@abc.com>\r\n" + "CC: Rrrrr rrede <sssss.rv@abc.com>, Dsssssf V R\r\n"
+ " <dsdsdsds.vr@abc.com>, Psssss A <pssss.a@abc.com>, Logistics\r\n"
+ " <LOGISTICS@abc.com>, Gssss Bsss P <gdfddd.p@abc.com>\r\n"
+ "Subject: RE: [MyApps] (PRO-34604) PR for Additional Monitor allocation [CITS\r\n"
+ " Ticket:258849]\r\n" + "Thread-Topic: [MyApps] (PRO-34604) PR for Additional Monitor allocation\r\n"
+ " [CITS Ticket:258849]\r\n" + "Thread-Index: AQHRXMJHE6KqCFxKBEieNqGhdNy7Pp8XHc0A\r\n"
+ "Date: Mon, 1 Feb 2016 17:56:17 +0530\r\n"
+ "Message-ID: <B7F84439E634A44AB586E3FF2EA0033A29E27E47@JETWINSRVRPS01.abc.com>\r\n"
+ "References: <JA.101.1453963700000@myapps.abc.com>\r\n"
+ " <JA.101.1453963700000.978.1454311765375@myapps.abc.com>\r\n"
+ "In-Reply-To: <JIRA.450101.1453963700000.978.1454311765375@myapps.abc.com>\r\n"
+ "Accept-Language: en-US\r\n" + "Content-Language: en-US\r\n" + "X-MS-Has-Attach:\r\n"
+ "X-MS-Exchange-Organization-SCL: -1\r\n"
+ "X-MS-TNEF-Correlator: <B7F84439E634A44AB586E3FF2EA0033A29E27E47@JETWINSRVRPS01.abc.com>\r\n"
+ "MIME-Version: 1.0\r\n" + "X-MS-Exchange-Organization-AuthSource: TURWINSRVRPS01.abc.com\r\n"
+ "X-MS-Exchange-Organization-AuthAs: Internal\r\n" + "X-MS-Exchange-Organization-AuthMechanism: 04\r\n"
+ "X-Originating-IP: [1.1.1.7]";
Pattern pattern = Pattern.compile("To:(.*<([^>]*)>).*Message-ID", Pattern.DOTALL);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
Pattern innerPattern = Pattern.compile("<([^>]*)>");
Matcher innerMatcher = innerPattern.matcher(matcher.group(1));
while (innerMatcher.find()) {
System.out.println("-->:" + innerMatcher.group(1));
}
}
这里工作正常。我首先将部分从To
分组到Message
这是必需的部分。然后我有另一个分组来提取电子邮件ID。
有没有更好的方法来做到这一点?我们可以使用一个模式匹配器来完成它吗?
更新: 这是预期的输出:
-->:sssss.r@abc.com
-->:sssss.rv@abc.com
-->:dsdsdsds.vr@abc.com
-->:pssss.a@abc.com
-->:LOGISTICS@abc.com
-->:gdfddd.p@abc.com
答案 0 :(得分:2)
理想情况下,您可以使用外观:
(?<=To:.*)<([^>]+)>(?=.*Message-ID)
的可视化
不幸的是,Java doesn't support variable length in lookbehinds。解决方法可能是:
(?<=To:.{0,1000})<([^>]+)>(?=.*Message-ID)
答案 1 :(得分:1)
我认为您正在查找<...>
之后和To:
之前的Message-ID
内的所有电子邮件。因此,您可以使用基于\G
的正则表达式进行一次传递:
Pattern pt = Pattern.compile("(?:\\bTo:|(?!^)\\G).*?<([^>]*)>(?=.*Message-ID)", Pattern.DOTALL);
Matcher m = pt.matcher(input);
while (m.find()) {
System.out.println(m.group(1));
}
正则表达式匹配:
(?:\\bTo:|(?!^)\\G)
- 前导边界,To:
整个单词或上一次成功匹配后的位置.*?
- 任何字符,第一个<([^>]*)>
- 以<
开头的子字符串,后跟除>
(第1组)以外的零个或多个字符,后跟关闭>
(?=.*Message-ID)
- 一个积极的前瞻,确保在当前比赛之前某处有Message-ID
。