【问题标题】:How can I use a regex to match multiple address lines?如何使用正则表达式匹配多个地址行?
【发布时间】:2016-03-08 13:14:21
【问题描述】:

鉴于以下示例文本,我是否可以使用正则表达式来匹配每个地址的每一行,并添加标记以了解一个地址何时结束而下一个地址何时开始?目前,我知道如何匹配每个完整的地址。然后我可以运行第二个正则表达式来挑选单独的行,但是是否有可能一次性完成这两个步骤?

Address:
Address 1 line 1,
Address 1 line 2,
Address 1 line 3

Address:
Address 2 line 1,
Address 2 line 2,
Address 2 line 3,
Address 2 line 4

Address:
Address 3 line 1,
Address 3 line 2

【问题讨论】:

  • 使用Matcher#appendReplacement
  • 谢谢 Wiktor,我不知道这种方法。但是,我仍在研究如何使用它来挑选地址行。它似乎是一种用指定字符串替换匹配项的方法,并且仍然需要一个正则表达式来匹配每个地址行。
  • 对不起,我不知道如何帮助你,因为我不清楚最终输出。

标签: java regex


【解决方案1】:

这是一个带有DOTALL 标志的Pattern,可以使用"Address:" 字符串作为分隔符来查找多行:

// for test
String addresses = "Address:" + System.getProperty("line.separator")
        + "Address 1 line 1," + System.getProperty("line.separator")
        + "Address 1 line 2," + System.getProperty("line.separator")
        + "Address 1 line 3"
        + "Address:" + System.getProperty("line.separator")
        + "Address 2 line 1," + System.getProperty("line.separator")
        + "Address 2 line 2," + System.getProperty("line.separator")
        + "Address 2 line 3";
//                           | look behind for "Address:"
//                           |            | any 1+ character, 
//                           |            | reluctantly quantified
//                           |            |  | lookahead for "Address:"
//                           |            |  | or end of input
//                           |            |  |            | dot can mean
//                           |            |  |            | line separator
Pattern p = Pattern.compile("(?<=Address:).+?(?=Address:|$)", Pattern.DOTALL);
Matcher m = p.matcher(addresses);
// iterating matches within given string, and printing
while (m.find()) {
    System.out.printf("Found: %s%n%n", m.group());
}

输出

Found: 
Address 1 line 1,
Address 1 line 2,
Address 1 line 3

Found: 
Address 2 line 1,
Address 2 line 2,
Address 2 line 3

注意

为了从匹配中排除 "Address:" 标记之后的行分隔符,您可以使用这种精炼模式:

Pattern p = Pattern.compile("(?<=Address:"
    + System.getProperty("line.separator")+").+?(?=Address:"
    + System.getProperty("line.separator")+"|$)", 
    Pattern.DOTALL
);

【讨论】:

  • 谢谢梅娜。如果我正确理解您的帖子,您的正则表达式匹配两次,一次用于地址 1 行,一次用于地址 2 行。但是,我想要的是每个地址行(即地址 1 第 1 行、地址 1 第 2 行等)都匹配,以保持这些行彼此分开。
【解决方案2】:

如果正则表达式是你想要的......

如果地址中的行数有限(在您的示例 4 中),您可以通过以下方式获取它们:

Address:\s*?(?:\n(.*),)?(?:\n(.*),)?(?:\n(.*),)?(?:\n(.*),)?(?:\n(.*))

这里的文本Address: 标志着块的开始,四行被抓取,前三行是可选的。

(您需要全局标志。)

regex101 example.

【讨论】:

  • ClasG,谢谢,但是是的,不幸的是,我需要一个解决方案,该解决方案适用于程序事先不知道最大地址行数的地址列表。
猜你喜欢
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 2012-03-12
  • 2012-04-27
  • 1970-01-01
相关资源
最近更新 更多