jsoupを使用して表の内容を展開し、Regexのコンテンツの位置決めを容易にする

8119 ワード

背景
最近のプロジェクトでは、ネット上から一部のデータをキャプチャする必要があり、正則を使ってデータをマッチングし、抽出する際に、表類のデータが表の頭とデータの部分が分離しているため、このようなデータを直接位置決めするのは、一定の困難があることがわかりました(よし、認めました.自分には良い解決策がありません_).したがって、簡略化して解析前にコンテンツを前処理し、後続の正規解析を容易にする.例えば、冗長性により、表の頭の内容をコンテンツの前に付加し、特殊な記号で区切ることで、正規は抽出コンテンツを正確に位置決めすることができる.
一歩
構想はあって、第1の問題は、表の行、列の合併(rowspan、colspan)の問題で、それでは表を展開する必要があって、コードは1つの2次元の表の展開の方法で、しかし生産環境の下でまた同時のこのような問題を解決しなければならなくて、ここで展開しません
じょうふごう
ライブラリJSoupを使用します.詳細は公式ドキュメントを参照してください.
表の変換
import java.io.FileInputStream;
import java.io.InputStream;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;

public class TableConvert {
/**
     *          
     * @param table
     * @return
     */
    public Element[][] toTable(Element table) {
        if (!table.nodeName().equals("table")) {
            return null;
        }

        Elements tableRows = table.getElementsByTag("tr");
        int tableHeight = tableRows.size();

        //         ,    :           colspan        2,     
        int tableWidth = 0;
        for (int tr_idx = 0; tr_idx < tableHeight; tr_idx++) {
            Elements tds = tableRows.get(tr_idx).select("td, th");
            int td_size = tds.size();
            if (td_size > tableWidth)
                tableWidth = td_size;
        }

        System.out.println("tableHeight:"+tableHeight+";tableWidth:"+tableWidth);
        
        if (tableHeight < 2 || tableWidth < 2)
            return null;

        //      
        Element[][] result = new Element[tableHeight][tableWidth];

        //  canreplace    
        for(int i=0;i tableWidth ,      
        try {
            for (int rowIndex = 0; rowIndex < tableHeight; rowIndex++) {
                Elements colCells = tableRows.get(rowIndex).select("td, th");

                System.out.println("row"+rowIndex+":
"+colCells); int pointIndex = 0;// for (int colIndex=0; colIndex < colCells.size();colIndex++) { Element currentCell=colCells.get(colIndex); // if(result[rowIndex][colIndex].tagName().equalsIgnoreCase("canreplace")) { result[rowIndex][colIndex] = currentCell; pointIndex=colIndex; }else { pointIndex=colIndex+1; // while(!result[rowIndex][pointIndex].tagName().equalsIgnoreCase("canreplace") && pointIndex< tableWidth ) { pointIndex++; System.out.println("===rowIndex==="+pointIndex+"====tempColIndex==="+pointIndex+"==="+result[rowIndex][pointIndex].tagName()); } if(pointIndex < tableWidth && result[rowIndex][pointIndex].tagName().equalsIgnoreCase("canreplace") ) { result[rowIndex][pointIndex] = currentCell; }else { throw new Exception("table !"); } } // colspan int colspan = 1; if (currentCell.hasAttr("colspan")) { colspan = Integer.valueOf(currentCell.attr("colspan")); currentCell.removeAttr("colspan"); } // if (colspan > 1) { for(int emptyColindex =1;emptyColindex < colspan ;emptyColindex++) { pointIndex++; while(!result[rowIndex][pointIndex].tagName().equalsIgnoreCase("canreplace") && pointIndex< tableWidth ) { pointIndex++; System.out.println("===rowIndex==="+pointIndex+"====tempColIndex==="+pointIndex+"==="+result[rowIndex][pointIndex].tagName()); } if(pointIndex < tableWidth && result[rowIndex][pointIndex].tagName().equalsIgnoreCase("canreplace") ) { result[rowIndex][pointIndex] = currentCell; }else { throw new Exception("table !"); } } } // rowspan int rowspan = 1; if (currentCell.hasAttr("rowspan")) { rowspan = Integer.valueOf(currentCell.attr("rowspan")); currentCell.removeAttr("rowspan"); } if (rowspan > 1) { for (int i = 1; i < rowspan; i++) { if (i >= tableHeight) break; // ignore bad rowspans System.out.println("===rowIndex==="+pointIndex+"====tempColIndex==="+pointIndex+"==="+result[rowIndex][pointIndex].tagName()); result[rowIndex+i][colIndex] = currentCell;//new Element(invalidTag, ""); } } } } } catch (Exception e) { e.printStackTrace(); return null; } return result; }

補助印刷
    public void printTable(Element[][] table) {
        if (table == null) return;

        System.out.println("==================");
        for (int rowIndex = 0; rowIndex < table.length; rowIndex++) {
            System.out.print("|");
            for (int colIndex = 0; colIndex < table[rowIndex].length; colIndex++) {
                if (table[rowIndex][colIndex] == null) {
                    System.out.print("  ");
                } else {
                    System.out.print(table[rowIndex][colIndex].text());
                }
                System.out.print(" |");
            }
            System.out.println();
        }
        System.out.println("==================");
    }

テストの実行
public static void main(String[] args) {
        String url = "d:\\Untitled-2.html";
        InputStream in;
        TableConvert tableConvert = new TableConvert();
        try {
            in = new FileInputStream(url);;
            Document doc = Jsoup.parse(in, null, "");

            for (Element aTable : doc.getElementsByTag("table")) {
                Elements subtables = aTable.getElementsByTag("table");
                subtables.remove(aTable);
                if(subtables.size() == 0) {
                    System.out.println("converting table...");
                    Element[][] result = tableConvert.toTable(aTable);
                    if (null != result)
                        tableConvert.printTable(result);
                    else
                        System.out.println("Could not convert table.");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ファイル内容のテスト
1
2