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

Java 用于将德语地址拆分为多个部分的正则表达式,java,regex,split,street-address,Java,Regex,Split,Street Address,晚上好, 我正试图通过Java将德语地址字符串的各个部分拆分为不同的部分。有人知道正则表达式或库可以做到这一点吗?要按如下方式拆分它: 道路名称25a 88489测试站 到 Teststadt街25a街88489街名称 或 Teststr。388489贝斯皮洛特(格罗·克莱斯) 到 Teststr.| 3 | 88489 |贝斯皮洛特(Großer Kreis) 如果系统/正则表达式在邮政编码或城市等部分丢失的情况下仍能正常工作,那就太完美了 有没有任何正则表达式或库可以用来存档 编辑:德文地址

晚上好,

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

道路名称25a 88489测试站


Teststadt街25a街88489街名称

Teststr。388489贝斯皮洛特(格罗·克莱斯)


Teststr.| 3 | 88489 |贝斯皮洛特(Großer Kreis)

如果系统/正则表达式在邮政编码或城市等部分丢失的情况下仍能正常工作,那就太完美了

有没有任何正则表达式或库可以用来存档

编辑:德文地址规则:
街道:字符、数字和空格
门牌号:数字和任何字符(或空格),直到一系列数字(zip)(至少在这些示例中)
邮政编码:5位数

地点或城市:其余部分也可能带有空格、逗号或大括号。乍一看,似乎一个简单的空格就可以了,但是仔细看,我发现地址总是有4个部分,第一部分可以有空格

我会这样做(psudeocode):


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

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

正则表达式模式:

^([^0-9]+) ([0-9]+.*?) ([0-9]{5}) (.*)$
  • 第一组:街道
  • 第二组:第二号住宅
  • 第3组:拉链
  • 第4组:城市
试试这个:

^[^\d]+[\d\w]+(\s)\d+(\s).*$
它为每个空格捕获组,这些空格分隔地址的4个部分中的1个部分

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

^([^\d]+)([\d\w]+)\s(\d+)\s(.*)$
我不懂java,所以不确定用于替换捕获的组的确切代码。

publicstaticvoidmain(String[]args){
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");
                }
String data=“Name der Strase 25a 88489 Teststadt”; 字符串regexp=“([a-zA-z]+)([\\w]+)(\\d+)([a-zA-z]+)”; Pattern=Pattern.compile(regexp); Matcher Matcher=pattern.Matcher(数据); 布尔matchFound=matcher.find(); 如果(找到匹配项){ //获取此比赛的所有组
对于(int i=0;i我会从后面开始,因为据我所知,城市名称不能包含数字(但可以包含空格(我找到的第一个示例:)。然后前面的五位数必须是邮政编码

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

不管怎样,我们走吧:

^((?:\p{L}| |\d|\.|-)+?) (\d+(?: ?- ?\d+)? *[a-zA-Z]?) (\d{5}) ((?:\p{L}| |-)+)(?: *\(([^\)]+)\))?$
这甚至可以正确解析诸如“Straße des 17.Juni 23-25 12345柏林手套”之类的神秘地址

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

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

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

^
(?<street>(?:\p{L}|\ |\d|\.|-)+?)\ 
(?<number>\d+(?:\ ?-\ ?\d+)?\ *[a-zA-Z]?)\ 
(?<zip>\d{5})\ 
(?<city>(?:\p{L}|\ |-)+)
(?:\ *\((?<suffix>[^\)]+)\))?
$
^
(?(?:\p{L}\\\\\d\.-)+?)\
(?\d+(?:\?-\?\d+)\*[a-zA-Z]?)\
(?\d{5})\
(?(?:\p{L}\\\\\-)+)
(?:\ *\((?[^\)]+)\))?
$
在Java 7中,我们最接近的结果是(未经测试;可能包含拼写错误):

字符串模式=
"^" +
“(?(?:\\p{L}| | \\d | \.\124;-)+?”+
“(?\\d+(?:?-?\\d+)*[a-zA-Z]?”+
“(?\\d{5})”+
“(?(?:\\p{L}| |-)+”+
"(?: *\\((?[^\\)]+)\\))?" +
"$";

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

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

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

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

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

对于那些不熟悉德国地址的人,规则是什么?是“有空格但没有数字的东西”、“有数字但没有空格的东西”,“数字和无空格”,“无数字和无空格”?您不需要正则表达式。只需使用空格分隔符拆分字符串,然后使用bar
|
delimeter将其连接起来-但是Oli上面的评论也很相关,因为我假设德语地址与spaces@OliCharlesworth:编辑post@Robbie字体我不能用空格来划分,因为一个街道名称和一个城市/place也可以包含空格。不要认为这很容易。有很多街道名称中都有空格。此外,有些人写的是“25a”而不是“25a”。我通常会用“,”来分隔部分。你是从其他系统中以定义的格式获取地址吗?这个正则表达式被破坏了,因为街道名称可以包含空格以数字表示。例如(但不限于此),在指定名称之前,可以对街道进行编号,以便最终得到“Straße 42”。另一个例子是“Straße des 17.Juni”.OP没有提到街道名称中的数字。也许没有必要保留这些数字?@KonradRudolph你是对的。这是一种可能性,我完全忘记了。有没有一个“系统”可以用来定义德语地址是如何建立的?@KonradRudolph这个问题清楚地将街道部分定义为“街道:字符和空格直到一个数字”所以我的正则表达式没有被破坏。我只是回答了这个问题。如果,正如克里斯蒂安所证实的,这个问题是不正确的
/^([a-zäöüß\s\d.,-]+?)\s*([\d\s]+(?:\s?[-|+/]\s?\d+)?\s*[a-z]?)?\s*(\d{5})\s*(.+)?$/i
[a-zäöüß\s\d,.-]+?                         # Street name (lazy)
[\d\s]+(?:\s?[-|+/]\s?\d+)?\s*[a-z]?)?     # Street number (optional)