You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java正则提取地址块信息:排除额外行的匹配异常问题

Java正则提取地址字段的优化方案

问题背景

我原本用以下Java正则提取地址块信息:

\b(?!(?i)Doctor| )([^\s]*\b)[\n\r\s]+(\b[\S\s][^\d]*\b)[\s\S]+([0-9]{5})\s+([\D]*)

正常地址示例:

Doctor John DOE
123 dream road 
12345 TOWN

对应的提取代码:

firstName = matcher.group(1).trim();
lastName = matcher.group(2).trim();

这个正则在正常格式下能正确提取名和姓,但当地址块包含额外行时(如下示例),提取的姓会错误匹配为DOE Country Hospital:

Doctor John DOE
Country Hospital
123 dream road 
12345 TOWN

我需要能分别提取名、姓、地址行1(可选)、地址行2、邮编、城镇这几个字段,但找不到合适的正则模式。

优化后的正则方案

针对地址块的结构特征(姓名行以Doctor开头,邮编为固定5位数字,最后一行是邮编+城镇),调整后的正则如下:

(?i)^Doctor\s+([^\s]+)\s+([^\n\r]+)\n\r?((?:[^\n\r]+\n\r?)?)[^\d]*?(\b\d{5})\s+([^\n\r]+)$

正则各部分解释

  • (?i)^Doctor\s+:忽略大小写匹配开头的Doctor,后跟任意空白字符
  • ([^\s]+):捕获名(姓名行中第一个空白前的非空白内容)
  • \s+([^\n\r]+):捕获姓(姓名行剩余的非换行内容)
  • \n\r?:兼容Windows/Unix格式的换行符
  • ((?:[^\n\r]+\n\r?)?):捕获可选的地址行1(非换行内容+换行,整个组为可选)
  • [^\d]*?:非贪婪模式匹配地址行2前的任意非数字内容,避免过度匹配
  • (\b\d{5}):捕获5位邮编
  • \s+([^\n\r]+)$:捕获城镇(邮编后的非换行内容,直到文本结尾)

Java提取代码示例

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AddressExtractor {
    public static void main(String[] args) {
        String regex = "(?i)^Doctor\\s+([^\\s]+)\\s+([^\\n\\r]+)\\n\\r?((?:[^\\n\\r]+\\n\\r?)?)[^\\d]*?(\\b\\d{5})\\s+([^\\n\\r]+)$";
        Pattern pattern = Pattern.compile(regex);

        // 正常地址测试
        String normalAddr = "Doctor John DOE\n123 dream road \n12345 TOWN";
        Matcher matcher = pattern.matcher(normalAddr);
        if (matcher.find()) {
            System.out.println("正常地址提取结果:");
            System.out.println("名:" + matcher.group(1).trim());
            System.out.println("姓:" + matcher.group(2).trim());
            System.out.println("地址行1(可选):" + (matcher.group(3).isEmpty() ? "无" : matcher.group(3).trim()));
            System.out.println("地址行2:" + normalAddr.substring(matcher.end(3), matcher.start(4)).trim());
            System.out.println("邮编:" + matcher.group(4).trim());
            System.out.println("城镇:" + matcher.group(5).trim());
        }

        // 含额外行的地址测试
        String extraLineAddr = "Doctor John DOE\nCountry Hospital\n123 dream road \n12345 TOWN";
        matcher = pattern.matcher(extraLineAddr);
        if (matcher.find()) {
            System.out.println("\n含额外行的地址提取结果:");
            System.out.println("名:" + matcher.group(1).trim());
            System.out.println("姓:" + matcher.group(2).trim());
            System.out.println("地址行1(可选):" + matcher.group(3).trim());
            System.out.println("地址行2:" + extraLineAddr.substring(matcher.end(3), matcher.start(4)).trim());
            System.out.println("邮编:" + matcher.group(4).trim());
            System.out.println("城镇:" + matcher.group(5).trim());
        }
    }
}

提取说明

  • 地址行1对应可选的额外行(如示例中的Country Hospital),无额外行时显示为“无”
  • 地址行2通过截取地址行1结束到邮编开始的内容获取,确保无论是否有额外行都能正确提取

内容的提问来源于stack exchange,提问作者anakin59490

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:10:30