使用正则表达式清洗邮政地址(spark regexp_extract)

1 投票
1 回答
58 浏览
提问于 2025-04-13 15:56

我想要截断一些地址的末尾:
"1 rue de l'église" => "1 rue de l'église"
"2 rue de la poste appartement B" => "2 rue de la poste"
"3 4 rue de la mairie 2eme étage" => "3 4 rue de la mairie"

规则是:如果在地址中间找到了一个数字或者关键词(比如“appartement”或“escalier”),那么就在它之前截断地址。

开头的部分显然是像 "^([0-9 ]*" 这样的,但我不知道怎么说“如果没有数字或者‘appartement’或者‘escalier’,就取这些字符”。

我尝试过的一种方法:

my_df.select("adresse_rue").withColumn(
    "adresse_rue", 
    f.regexp_extract(
        "adresse_rue",
        r'^([0-9 ]*[^(0-9| appartement | escalier )]*)([0-9]| appartement | escalier )?.*$',
        0)).take(20)

也许 ?:?! 可以帮忙,但我还没找到具体怎么用。

1 个回答

0

你在使用正则表达式的方向上是对的。你可以用一个叫做负向前瞻的东西,写成(?!pattern),来达到你想要的效果。下面是你可以怎么修改你的正则表达式:

r'^(?:(?! +(?:\d+[a-z]|appartement|escalier)).)*'

解释:

  • (?:\d+[a-z]|appartement|escalier)可以匹配你的关键词(比如“appartement”或“escalier”,或者是任何一串数字后面跟着一个字母)。
  • (?! +(?:\d+[a-z]|appartement|escalier))的意思是“后面不能跟着至少一个空格和关键词”。
  • (?:(?! +(?:\d+[a-z]|appartement|escalier)).)*会在每个匹配的字符之前进行这个检查。

你可以在这里查看演示

编辑

如果你还想排除第一个之后的任何数字(比如“2”,但“2eme”除外),可以用下面的表达式:

r'^[\d ]*(?:(?! +(?:\d|appartement|escalier)).)*'

另外,如果你还想排除出现在单词中间的数字(像“A2”),可以用下面的表达式:

r'^[\d ]*(?:(?! +(?:[^\s]*\d|appartement|escalier)).)*'

你可以在这里查看第二个演示

撰写回答