【问题标题】:How to print only certain sections of a string?如何仅打印字符串的某些部分?
【发布时间】:2018-08-24 22:20:25
【问题描述】:

首先 - 请原谅我,因为我是业余爱好者。

对于一个项目,我将一个包含小猫列表的 excel 文件作为输入,我想输出找到这些小猫的地址。

我已经实现了代码,因此小猫是一个具有名称、ID 和注释的对象(小猫通过评估 excel 文档中的每个单元格被分配了这些属性)。注释部分包含有关小猫在何处被发现的信息。

Excel document: 

name | ID | Notes
--------------------
Kit  | 5  | Great animal! Haha! Found at 1234 east 
     |    |   street. Incredibly ugly. 
---------------------
Kat  |  2 | Wow, what a charmer. from location 3456 
     |    | Dusk road
    .
    .
    .

目前,我的程序将 excel 文档转换为字符串,并为每只小猫打印整个“注释”部分。我希望它从字符串的其余部分中提取地址(尝试获取尽可能多的地址),所以输出看起来像这样:

    1234 east street, 3456 Dusk Road, ... 

我在网上只能找到关于 String delims 等的信息,但我不知道如何开始考虑从一个很长的字符串中提取特定的短语。有什么方法可以记录某个关键词的信息,比如“Found at”或“from location”,然后停在一段时间?

不将每个地址转换为一个长字符串,而是打印出每只小猫的提取地址会更容易吗?

我的代码(供参考):

 public class Kitten {
     private String name;
     private String animalID;
     private String addressFound;


     public Kitten() {
        super();
        this.name = name;
        this.animalID = animalID;
        this.addressFound = addressFound;
     }

    //getters and setters

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getAnimalID() {
        return animalID;
    }

    public void setAnimalID(String animalID) {
        this.animalID = animalID;
    }

    public String getAddress() {
        return addressFound;
    }

    public void setAddress(String addressFound) {
        this.addressFound = addressFound;

    }
 }

输入:带有小猫信息的 excel 文件。打印“注释”部分 每只小猫

 public class ReadExcel {

     public void printer() {
        try {

            FileInputStream kittenFile = new FileInputStream(new 
                                    File("./IntakeNotesSimple.xlsx"));

            XSSFWorkbook wb = new XSSFWorkbook(kittenFile);
            XSSFSheet sheet = wb.getSheetAt(0);

            ArrayList<Kitten> kittenList = new ArrayList<>();
            for (int i= sheet.getFirstRowNum() + 1; i<= sheet.getLastRowNum(); 
                                i++) {
                Kitten k = new Kitten();
                Row r = sheet.getRow(i);

                for (int j = r.getFirstCellNum(); j<= r.getLastCellNum(); j++) 
                {
                        Cell c = r.getCell(j);

                        if (j==0) {
                            k.setName(c.getStringCellValue());
                        }


                        if (j==1) {
                            k.setAnimalID(c.getStringCellValue());
                        }
                        if (j==2 && (c != null)) {
                            k.setAddress(c.getStringCellValue());
                        }

                }
                kittenList.add(k);

            }

            for (Kitten kit: kittenList) {
                 System.out.println(kit.getAddress() +"\n" +);
            }

            wb.close();

        }
        catch(Exception e) { 
            e.printStackTrace();
        }
     }
 }



public class PrintOut {
    public static void main(String[] args) throws FileNotFoundException {
        ReadExcel addresses = new ReadExcel();
        addresses.printer();
    }
}

【问题讨论】:

  • 你的小猫地址是不是有一定的规律?还是只包含随机单词?
  • 我并不是要捕获每只小猫的每个地址(因为有数百个条目),而只是尝试捕获大部分地址。 excel 文档中大约一半的 Notes 条目包含“发现于”字样,后跟实际地址。所以模式往往是“发现于”(然后是地址)“”。在注释部分。
  • 好吧,我添加了一个答案,可以帮助您实现您想做的事情

标签: java excel string text-extraction


【解决方案1】:

假设您有一个单词列表,可以为您提供地址的开头(实际上它不会有这么多可能性,但让我们想象一下,因为您建议这将在您的 OP 中起作用)。

您搜索的字符串将以一些字符开头,然后是“找到于”或“来自位置”,它将在下一个 , . !? 字符处结束。最后,最后一部分将包含一些其他字符。

您应该在这里使用的解决方案是 Regex,也就是您能找到的最佳模式匹配工具。上述模式的正则表达式是:

^.*?(found at|from location) (.*?)([\.,!?].*+|)$

这个正则表达式不是那么容易,所以我们可能不会详细介绍,我最好将你链接到这个正则表达式的一些可视化工具:https://regex101.com/r/q1w428/1

那么现在,如何在 java 应用程序中使用它?

  private static final String KITTEN_PATTERN_STRING = "^.*?(found at|from location) (.*?)([\\.,!?].*+|)$";

  private static final Pattern KITTEN_PATTERN = Pattern.compile(KITTEN_PATTERN_STRING);

  public String extractKittenAddress(String kittenString) {
       Matcher m = KITTEN_PATTERN.matcher(kittenString);

       if(m.matches()) 
          return m.group(2);
       return null;

  }

你去吧!

【讨论】:

    【解决方案2】:

    我假设你有一个包含一些文本和地址的字符串。你的分隔符是:

    发现于

    因此,您可以在迭代数据时拆分文本并提取地址,如下所示:

    public class Main {
        public static void main(String[]args) throws JsonProcessingException {
            String textContaintsAddress = "Great animal! Haha! Found at 1234 east street. Incredibly ugly.";
            String address[] = textContaintsAddress.split("Found at");
    
            if (address.length > 1) {
                System.out.println(address[1].trim());
            }else{
                System.out.println(textContaintsAddress);;
            }
        }
    }
    

    打印出来:

    1234 east street. Incredibly ugly.
    

    编辑您的代码如下:

    public class ReadExcel {
    
        public void printer() {
            try {
    
                FileInputStream kittenFile = new FileInputStream(new
                        File("./IntakeNotesSimple.xlsx"));
    
                XSSFWorkbook wb = new XSSFWorkbook(kittenFile);
                XSSFSheet sheet = wb.getSheetAt(0);
    
                ArrayList<Kitten> kittenList = new ArrayList<>();
                for (int i= sheet.getFirstRowNum() + 1; i<= sheet.getLastRowNum();
                     i++) {
                    Kitten k = new Kitten();
                    Row r = sheet.getRow(i);
    
                    for (int j = r.getFirstCellNum(); j<= r.getLastCellNum(); j++)
                    {
                        Cell c = r.getCell(j);
    
                        if (j==0) {
                            k.setName(c.getStringCellValue());
                        }
                        if (j==1) {
                            k.setAnimalID(c.getStringCellValue());
                        }
                        if (j==2 && (c != null)) {
                            // here we add the logic
                            String textContaintsAddress = c.getStringCellValue();
                            String address[] = textContaintsAddress.split("Found at");
    
                            if (address.length > 1) {
                                k.setAddress(address[1].trim());
                            }else{
                                k.setAddress(textContaintsAddress);;
                            }
    
                        }
    
                    }
                    kittenList.add(k);
                }
    
                for (Kitten kit: kittenList) {
                    System.out.println(kit.getAddress() +"\n" +);
                }
    
                wb.close();
    
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 2011-12-31
      • 2017-08-30
      相关资源
      最近更新 更多