【问题标题】:regex group isn't working for multiple addressses正则表达式组不适用于多个地址
【发布时间】:2019-07-05 15:06:40
【问题描述】:

我的正则表达式有问题。我必须读取包含联系人数据的文件并将其导入数据库。该行具有标准格式,我能够读取所有行,提取联系人姓名、街道/房屋编号、邮政编码和城市。我的问题是门牌号码可以是数字,也可以是“7/9”。

因为我的正则表达式只需要数字,所以第二个替代方案的导入由于斜线而不起作用。另一个问题是当城市名称由两部分组成时,城市也可以有斜线。

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

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

这里是地址部分。

  1. First Street 32 78224 firstCity
  2. Second Street 7/9 73430 secondCity
  3. Third Street 32 78224 third/City
  4. Fourth Street 9/7 73430 fourth/city

第一个和第三个例子都可以。我可以读取数据。但是第二个和第四个返回空字符串。

有人可以帮助我吗?

【问题讨论】:

  • 你能分享所有4(或5)部分的规格吗?
  • 正则表达式是否适合您的任务?地址可能包含诸如Harlow HouseSuite 1234 之类的附录,街道编号可能带有诸如69a 之类的后缀,可能根本没有街道名称(例如12 99999 Backwater);在德国曼海姆市,市中心没有街道名称,但街区由一种坐标代码引用(例如Q3 12345 city。好吧,这太极端了......)。这些“常见”格式的异常值会破坏你的代码,但除非你有很好的测试覆盖率,否则很难事先发现(更不用说支持它们会不成比例地破坏你的正则表达式)

标签: java regex regex-group


【解决方案1】:

我会看到一个更简单的正则表达式:^(?&lt;street&gt;\D*)\s(?&lt;number&gt;[\d\/]+)\s(?&lt;zip&gt;\d{5})\s(?&lt;city&gt;.*)$

  • street 是数字以外的任何东西
  • number 是数字/斜线
  • zip 是 5 位数字
  • city 是其余的

这很好地匹配您的 4 个字符串:regex demo

【讨论】:

  • street 模式对于像82nd Street 这样的短语会动摇,即。街道名称中的 hi 序数。
  • @collapsar 对,我只是遵循 OP 的要求,他关心的似乎是“街道编号 zip 城市”,他应该给出确切的规范
  • 是的,他应该,是的,这只是一个小细节,但我怀疑 OP 不会想到。
【解决方案2】:

您可以使用可选组:

^(?<street>[\pL\pN.]+(?:\h+[\pL\pN.]+)*)\h+(?<number>\d+(?:/\d+)?)\h+(?<zip>\d{5})\h+(?<city>\pL+)(?<suffix>/\pL+)?$

关于模式

  • ^ 字符串开始
  • (?&lt;street&gt;
    • [\pL\pN.]+ 匹配 1 次以上列出的任何一项
    • (?:非捕获组
      • \h+[\pL\pN.]+ 匹配 1 次以上列出的任何一项
    • )*关闭非捕获组并重复0+次
  • )\h+关闭街道组,匹配1+水平空白字符
  • (?&lt;number&gt;
    • \d+(?:/\d+)? 匹配 1+ 个数字和可选的 / 数字部分
  • )\h+关闭数字组,匹配1+水平空白字符
  • (?&lt;zip&gt;
    • \d{5} 匹配 5 位数字
  • )\h+ 关闭 zip 组,匹配 1+ 个水平空白字符
  • `(?\pL+) 匹配城市
  • (?&lt;suffix&gt;/\pL+)?匹配可选后缀
  • $字符串结束

Regex demo | Java demo

在 Java 中

String regex = "^(?<street>[\\pL\\pN.]+(?:\\h+[\\pL\\pN.]+)*)\\h+(?<number>\\d+(?:/\\d+)?)\\h+(?<zip>\\d{5})\\h+(?<city>\\pL+)(?<suffix>/\\pL+)?$";

【讨论】:

    猜你喜欢
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    相关资源
    最近更新 更多