【问题标题】:how to capture a specific data from the large string? [closed]如何从大字符串中捕获特定数据? [关闭]
【发布时间】:2019-05-24 09:30:05
【问题描述】:

我正在从 pdf 中提取数据并存储在字符串中,从这个大数据中我想在字段中存储一些特定的数据。

我已经尝试了一些代码,它正在工作,但是如何捕获所有需要的数据?

import java.io.FileInputStream;
import java.io.IOException;
import java.util.regex.Pattern;

import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

public class LdcReaderDemoNew {
    private static final Pattern END_OF_SENTENCE = Pattern.compile("\\.\\s+");

    public static void main(String[] args) throws IOException {
        String filePath = "C:\\Users\\Admin\\Downloads\\Ldc.pdf";
        String text = convertPDFToTxt(filePath);
         //String[] word = {"CERTIFICATE UNDER SECTION","Certificate No","rate of"};

        String word = "Certificate No";
        String str = getSentence(text, word);
        String str1[] = str.split(":");
        String[] str2 = str1[1].split(" ");
        System.out.println(str2[1]);
    }

    public static String convertPDFToTxt(String filePath) throws IOException {
        byte[] thePDFFileBytes = readFileAsBytes(filePath);
        PDDocument pddDoc = PDDocument.load(thePDFFileBytes);
        PDFTextStripper reader = new PDFTextStripper();
        String pageText = reader.getText(pddDoc);
        pddDoc.close();
        return pageText;
    }

    private static byte[] readFileAsBytes(String filePath) throws IOException {
        FileInputStream inputStream = new FileInputStream(filePath);
        return IOUtils.toByteArray(inputStream);
    }

    public static String getSentence(String text, String word) {
        final String lcword = word.toLowerCase();
        return END_OF_SENTENCE.splitAsStream(text).filter(s -> s.toLowerCase().contains(lcword)).findAny().orElse(null);
    }

}

例如“我有证书编号:0218AU464E”我想将 0218AU464E 存储在一个字符串中。同样,我想在单独的字段中捕获以下数据。

1)195(2)

2)0218AU464E

3)MUMT17510D

4)SHELF DRILLING OFFSHORE SERVICES ' INDIA ) PRIVATE LIMITED 地址 4TH FLOOR CHEMTEX

5)1218694350

6)4%

7)货架钻孔 C.E.THRONTON,LTD

8)AASCS2718N

9)01-APR -18

10)31-MAR-19

CERTIFICATE UNDER SECTION 195(2) OF THEINCOME TAX ACT, 1961 RELATING TO DEDUCTION OF 
TAX AT SOURCE 
Office of Assistant/Deputy  Commissioner ofIncome Tax 
INT TAX CIRCLE4(2)(1),M 

Certificate No : 0218AU464E Pnnt Date : 10-MAY-18 To, 
TAN  MUMT17510D 
Name SHELF DRILLING OFFSHORE SERVICES ' INDIA ) PRIVATE LIMITED Address 4TH FLOOR CHEMTEX 
HOUSE MAIN STREET POWAi MUMBAI 
MAHARASHTRA - 400076 


Ihereby authorl%e you to pay or credit Other sums upto Rs. 1218694350 after deducting income tax 
at the rate of 4 % (Excluding Education cess/surcharge as applicable) to or, as the case may be to the 
acoount of   SHELF DRILLING C.E.THRONTON,LTD.whose details are as below : 

PAN : AASCS2718N 
UnlUBranch : N A. 
Address : SHELF DRILLING C ETHRONTON LTD 4TH FLOOR CHEMTEX HOUSE MAIN STREET 
HIRANANDANIGARDENS POWAi MUMBAI 
MAHARASHTRA - 400076 

over whom I have jurisdiction forissue of this certificate. 

Th s certificate is non-transferable and valid for above PAN holder for payments or credit by 
whatever name called whichever is earlier from 01-APR -18 to 31-MAR-19, unless It Is cancelled by 
me under intimation to you before that date. 
The above certificate number should be quoted in the quarter y TDS statement for the relevant

【问题讨论】:

  • pdf 是否始终具有相同的格式?例如,pdf 是否总是以 'CERTIFICATE UN SECTION "XXX" OF '..
  • 是的,它将从“CERTIFICATE UNDER SECTION”开始

标签: java arrays regex string


【解决方案1】:

这可以通过使用捕获组以非常肮脏的方式完成。假设文本的总体布局每次都相同,并且只有 THOSE 值会改变,您可以使用以下内容:

/^.*?(?<=^CERTIFICATE UNDER SECTION )(\d+(?:\(\d+\))?).*?(?<=Certificate No : )([\dA-Z]+).*?(?<=TAN  )(MUMT[\dA-Z]+).*?(?<=Name )([^\n]+).*?(?<=Rs\. )(\d+).*?(?<=at the rate of )(\d+\s*%).*?(?<=of )\s*(.*?)\.whose details.*?(?<=PAN : )([A-Z\d]+).*?(?<= from )(.*?)(?= to ).*?(?<= to )(.*?),.*?$/s

这将提取 a) 整个字符串作为匹配项) 和 b) 您表示要提取为捕获组的值。

查看实际操作:

https://regex101.com/r/vODJyt/1

显然,虽然它可以工作,但正如我所说的那样,它很脏,但如果发生变化,它很容易失败,但您可以更新正则表达式以解决这些问题,但对于提供的字符串,这会立即提取您想要的所有值。

注意 - 您需要提供 single line/s 开关以允许 . 捕获 \n 字符

【讨论】:

  • 问题:你是怎么把这个正则表达式写得这么快的?
  • @ThanosM 没那么快……我只是复制/粘贴了他的字符串,然后在需要的地方添加了负面的后视,哈哈
  • 您的正则表达式和为整个字符串“(CERTIFICATE UNDER SECTION)(。*)(OF THE INCOME TAX ACT)”制作类似的东西有什么区别。这样你只需要捕获特定的正则表达式匹配后的组。
  • 再一次,假设它是相同/相似的......是的.*? 也可以在那里工作,但我想如果它们只是数字,可以强制执行。我已经更新了我的答案,使 \(\d\) 部分可选。
  • 这样更安全是的
【解决方案2】:

更好的是,使用实体提取 API。 named-entity-recognition

或者你可以做一件事,制作一个pdf的模板或格式。你可以解析它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 2021-06-09
    • 1970-01-01
    • 2012-10-31
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多