Regex将一个德国地址拆分为多个部分



晚上好,

我正试图通过Java将德语地址字符串的各个部分拆分为它的各个部分。有人知道正则表达式或库可以做到这一点吗?按如下方式拆分:

Name der Straße 25a 88489 Teststadt

Name der Straße|25a|88489|Teststadt

Teststr. 3 88489 Beispielort (Großer Kreis)

Teststr.|3|88489|Beispielort (Großer Kreis)

如果缺少邮政编码或城市等部分,那么system/regex仍然可以工作,那将是完美的。

有没有任何regex或库可以用来存档?

编辑:德语地址规则:
街道:字符、数字和空格
House no:数字和任何字符(或空格),直到一系列数字(zip)(至少在这些例子中是这样)
邮编:5位
地点或城市:其余的可能也有空格、逗号或大括号

我遇到了一个类似的问题,并对这里提供的解决方案进行了一点调整,得出了这个解决方案,它也有效,但(imo)更易于理解和扩展:

/^([a-zäöüßsd.,-]+?)s*([ds]+(?:s?[-|+/]s?d+)?s*[a-z]?)?s*(d{5})s*(.+)?$/i

以下是一些匹配示例。

它还可以处理丢失的街道编号,并且可以通过向字符类添加特殊字符来轻松扩展。

[a-zäöüßsd,.-]+?                         # Street name (lazy)
[ds]+(?:s?[-|+/]s?d+)?s*[a-z]?)?     # Street number (optional)

在那之后,必须有邮政编码,这是唯一绝对必要的部分,因为它是唯一不变的部分。邮政编码后的所有内容都被视为城市名称。

我会从后面开始,因为据我所知,城市名称不能包含数字(但它可以包含空格(我发现的第一个例子:"Weil der Stadt")。然后,在此之前的五位数字必须是邮政编码。

在此之前的数字(可能后跟一个字母)是街道编号。请注意,这也可以是范围。在此之前的任何东西都是街道名称。

不管怎样,我们开始了:

^((?:p{L}| |d|.|-)+?) (d+(?: ?- ?d+)? *[a-zA-Z]?) (d{5}) ((?:p{L}| |-)+)(?: *(([^)]+)))?$

这甚至可以正确解析诸如"Straßedes 17"之类的晦涩地址。Juni 23-25 a 12345 Berlin Mitte"。

请注意,这不适用于地址扩展(如"Gartenhaus"或"c/o…")。我不知道如何处理这些。我很怀疑是否有一个可行的正则表达式来表达这一切。

正如您所看到的,这是一个非常复杂的正则表达式,包含许多捕获组如果我会在代码中使用这样的表达式,我会使用命名捕获(Java7支持它们),并使用x标志将表达式分解成更小的小块。不幸的是,Java不支持这一点。这是因为它有效地使复杂的正则表达式无法使用。

不过,这里有一个更清晰的正则表达式:

^
(?<street>(?:p{L}| |d|.|-)+?) 
(?<number>d+(?: ?- ?d+)? *[a-zA-Z]?) 
(?<zip>d{5}) 
(?<city>(?:p{L}| |-)+)
(?: *((?<suffix>[^)]+)))?
$

在Java7中,我们能实现的最接近的是(未经测试;可能包含拼写错误):

String pattern =
    "^" +
    "(?<street>(?:\p{L}| |\d|\.|-)+?) " +
    "(?<number>\d+(?: ?- ?\d+)? *[a-zA-Z]?) " +
    "(?<zip>\d{5}) " +
    "(?<city>(?:\p{L}| |-)+)" +
    "(?: *\((?<suffix>[^\)]+)\))?" +
    "$";

这是我的建议,可以进一步微调,例如允许丢失零件。

Regex模式:

^([^0-9]+) ([0-9]+.*?) ([0-9]{5}) (.*)$
  • 第1组:街道
  • 第2组:门牌号
  • 第3组:ZIP
  • 第4组:城市
public static void main(String[] args) {
    String data = "Name der Strase 25a 88489 Teststadt";
    String regexp = "([ a-zA-z]+) ([\w]+) (\d+) ([a-zA-Z]+)";
    Pattern pattern = Pattern.compile(regexp);
    Matcher matcher = pattern.matcher(data);
    boolean matchFound = matcher.find();
    if (matchFound) {
        // Get all groups for this match
        for (int i=0; i<=matcher.groupCount(); i++) {
            String groupStr = matcher.group(i);
            System.out.println(groupStr);
        }
    }System.out.println("nothing found");
                }

我想它不适用于德语元音变音符,但你可以自己解决这个问题。不管怎样,这是一个很好的启动。

我建议你访问这个网站,这是一个关于正则表达式的好网站。祝你好运

乍一看,一个简单的空格就可以了,但仔细看,我注意到地址总是有4个部分,第一部分可以有空格。

我想做的是这样的事情(伪代码):

address[4] = empty
split[?] = address_string.split(" ")
address[3] = split[last]
address[2] = split[last - 1]
address[1] = split[last - 2]
address[0] = join split[first] through split[last - 3] with whitespace, trim trailing whitespace with trim()

然而,这将只处理一种形式的地址。如果地址是用多种方式写的,可能会更加棘手。

试试这个:

^[^d]+[dw]+(s)d+(s).*$

它为每个分隔地址的4个部分中的1个的空间捕获组

这个为每个地址部分提供分组:

^([^d]+)([dw]+)s(d+)s(.*)$

我不懂java,所以不确定用于替换捕获的组的确切代码。

最新更新