用于将德语地址拆分为其部分的正则表达式

时间:2012-03-25 20:14:19

标签: java regex split street-address

晚上好,

我正试图通过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)

如果系统/正则表达式仍然有效,如果邮政编码或城市等部分缺失,那将是完美的。

有没有我可以存档的正则表达式或库?

编辑:德国地址规则:
街道:人物,数字和空间
房屋号码:数字和任何字符(或空格),直到一系列数字(zip)(至少在这些例子中)
邮编:5位数
地方或城市:其余的也可能有空格,逗号或大括号

6 个答案:

答案 0 :(得分:12)

我遇到了类似的问题,并稍微调整了这里提供的解决方案,并找到了这个解决方案,它也有效,但(imo)有点简单易懂和扩展:

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

以下是一些example matches

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

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

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

答案 1 :(得分:5)

我从后面开始,因为据我所知,城市名称不能包含数字(但可以包含空格(我发现的第一个例子:“{{3}然后在那之前的五位数字必须是邮政编码。

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

无论如何,我们走了:

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

这正确地解析了神秘的地址,例如“Straßedes17. Juni 23-25 a 12345 Berlin-Mitte”。

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

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

不过,这是一个更易读的正则表达式:

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

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

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

答案 2 :(得分:2)

这是我的建议,可以进一步微调,例如:允许缺少部分。

正则表达式:

^([^0-9]+) ([0-9]+.*?) ([0-9]{5}) (.*)$
  • 第1组:街道
  • 第2组:众议院编号
  • 第3组:ZIP
  • 第4组:城市

答案 3 :(得分:1)

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");
                }

我想这对德语变音符号不起作用,但你可以自己解决这个问题。无论如何,这是一个很好的创业公司。

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

答案 4 :(得分:0)

乍一看它看起来像一个简单的空白就行了,但仔细观察我注意到地址总是有4个部分,第一个部分可以有空格。

我会做的是这样的事情(psudeocode):

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()

但是,这只会处理一种形式的地址。如果地址以多种方式编写,则可能会更加棘手。

答案 5 :(得分:0)

试试这个:

^[^\d]+[\d\w]+(\s)\d+(\s).*$

它捕获每个空格的组,这些空格分隔地址的4个部分中的1个

OR

这个给出了每个地址部分的组:

^([^\d]+)([\d\w]+)\s(\d+)\s(.*)$

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