【问题标题】:Separating an address line into House Number, Street name, and Apartment in Java or COBOL在 Java 或 COBOL 中将地址行分隔为门牌号、街道名称和公寓
【发布时间】:2014-04-09 20:50:30
【问题描述】:

我目前正在尝试找出获取地址行并将其分成三个字段的最佳方法,即文件、门牌号、街道名称和公寓号。值得庆幸的是,城市、州和邮编已经在列中,所以我只需要解析上面列出的三件事,但即使这样也很困难。我最初的希望是使用 SQL 在 COBOL 中执行此操作,但我认为我无法使用其他人在单独的问题线程中列出的 PATINDEX 示例,我不断收到 -440 SQL 代码。我的第二个想法是在Java中使用字符串作为数组并检查数组中的数字,然后是字母,然后比较“Apt”或类似的东西。到目前为止,我有这个尝试测试我最终想要做的事情,但是我正在超出数组的边界异常。

class AddressTest{
    public static void main (String[] arguments){
       String adr1 = "100 village rest court";
       String adr2 = "1000 Arbor lane Apt. 21-D";
       String[] HouseNbr = new String[9];
       String[] Street = new String[20];
       String[] Apt = new String[5];

       for(int i = 0; i < adr1.length();i++){
           String[] forloop = new String[] {adr1};
           if (forloop[i].substring(0,1).matches("[0-9]")){
               if(forloop[i+1].substring(0,1).matches("[0-9]")){
                   HouseNbr[i] = forloop[i];
               }
               else if(forloop[i+1].substring(0,1).matches(" ")){
               }
               else if(forloop[i].substring(0,1).matches(" ")){
               }
               else{
                   Street[i] = forloop[i];
               }
           }
       }

       for(int j = 0; j < HouseNbr.length; j++){
               System.out.println(HouseNbr[j]);
       }
       for(int k = 0; k < Street.length; k++){
           System.out.println(Street[k]);
       }
    }   
}

任何其他想法都会非常有帮助。

【问题讨论】:

  • 一些与此有些相似的问题曾经被一个非常聪明的建议回答,即使用谷歌地图 API 交叉候选地址。
  • @Leo,假设它足够快,这根本不是一个坏主意。 user311530 我相信还会有各种类型的付费服务。为什么你仍然需要这样做?数据输入是如何完成的?已验证,还是任何旧垃圾?如果你有邮编,你需要街道名称吗? (我不知道,没有做过美国地址)。在编码之前,研究一些其他的可能性,如果你需要编码,首先分析你所有的地址以获得这些数据 - 看看你可以处理什么样的百分比。
  • 在一家从事商业业务的公司工作了 7 年(80 年代),我可以根据亲身经验断言这个问题没有完整的解决方案。总会有您解析错误的地址。您必须回答的问题是“您愿意为多少准确度付费?”。你可以很便宜地达到 90%,但从那时起,开发时间和特殊情况处理的成本成倍增加。如果您必须处理外国地址,您将分别为每个国家和/或地区开发逻辑。
  • 幸好没有国际地址。我认为基于所有建议,我对如何攻击它有了一个很好的了解。

标签: java sql street-address


【解决方案1】:

我会考虑删除不必要的数组并使用 StringTokenizer...

public static void main(String[] args) {

     String number;
     String address;
     String aptNumber;


    String str = "This is String , split by StringTokenizer";
    StringTokenizer st = new StringTokenizer(str);

    System.out.println("---- Split by space ------");
    while (st.hasMoreElements()) {
                String s = System.out.println(st.nextElement());

                if (StringUtils.isNumeric(s) {
                    number = s;
                    continue;  
            }   

                if(s.indexOf("Apt")) {
                   aptNumber = s.substring(s.indexOf("Apt"),s.length-1);
                   continue;
                }

    }

    System.out.println("---- Split by comma ',' ------");
    StringTokenizer st2 = new StringTokenizer(str, ",");

    while (st2.hasMoreElements()) {
        System.out.println(st2.nextElement());
    }
}

【讨论】:

  • 然后呢?这对识别“门牌号、街道名称和公寓号”有何帮助?
  • 字符串分词器没有任何方法可以验证 nextElement() 是否为数字?
  • 提取地址并不总是那么容易......第一个元素应该给你门号,剩下的就是输入街道名称。 if (st.nextElement).indexOf("Apt") > 0) 应该表明你是否有一个 apt 并从地址中提取它。
  • 如果我修改它以在我的 SQL 之后执行 substring(0,1).matches("[0-9]")(而不是读取文件中的示例)? mkyong.com/java/java-stringtokenizer-example
  • 你当然可以使用 apache.commons 来做 StringUtils.isNumeric
【解决方案2】:

如果您利用免费提供的美国邮政服务邮政编码查找器 (https://tools.usps.com/go/ZipLookupAction!input.action),您可以获取标准化格式的地址。 USPS 记录了该格式的有效选项,这将使编写非常复杂的正则表达式或许多简单的正则表达式来阅读标准表单变得更加容易。

【讨论】:

    【解决方案3】:

    我仍在努力,但对于将来可能需要这样做的任何人:

    import java.util.Arrays;
    import java.util.StringTokenizer;
    import org.apache.commons.lang3.*;
    
    class AddressTest{
    public static void main (String[] arguments){
       String adr1 = "100 village rest court";
       //String adr2 = "1000 Arbor lane Apt. 21-D";
       String reader = new String();
       String holder = new String();
       StringTokenizer a1 = new StringTokenizer(adr1);
       String[] HouseNbr = new String[9];
       String[] StreetName = new String[20];
       String[] Apartment = new String[5];
       int counter = 0;
    
       while(a1.hasMoreElements()){
           reader = a1.nextElement().toString();
           System.out.println("Reader: " + reader);
           if(StringUtils.isNumeric(reader)){
               String[] HNBR = reader.split("");
               for(int i = 1; i <= reader.length();i++){
                   System.out.println("HNBR:_" + HNBR[i]);
                   HouseNbr[i-1] = HNBR[i];   
               }
           }
           else if(StringUtils.startsWith(reader, "Apt.")){
               holder = a1.nextElement().toString();
               String[] ANBR = holder.split("");
               for(int j = holder.length(); j >= 0;j--){
                   Apartment[j] = ANBR[j];
               }
    
           }
           else{
               String STR[] = reader.split("");
               for(int k = 1; k <= reader.length();k++){
                   if(counter == StreetName.length){
                       break;
                   }
                   else{
                       StreetName[counter] = STR[k];
                       if(counter < StreetName.length){
                           counter++;
                       }
                   }
               }
               if((counter < StreetName.length) && a1.hasMoreElements()){
                   StreetName[counter] = " ";
                   counter++;
               }
           }
    
       }
       System.out.println(Arrays.toString(HouseNbr) + " " + Arrays.toString(StreetName)                
           + " " + Arrays.toString(Apartment));
        }   
    }
    

    【讨论】:

    • 我想你会为自己做很多工作,却得不到这么好的结果。请记住,除非您的地址已被规范化,否则您将获得 Apt、Appt、Art、Apat、Apartment、Aot、Spt 以及更多类似的内容,包括大小写和标点符号的变化。
    • 我检查了我们的数据库,我们根本没有很多公寓...如果是的话,也许 %1。我可能会添加另一个带有另一个变体的 if 语句,但就我的目的而言,允许它们不会太难。
    • 好的。反正我已经安排你可以投票了。祝你好运。
    • 非常感谢您的帮助!
    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多