STACKの使い方 -- java.util.Stack

戻る

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.util.concurrent.*;

/**
* <pre>
* $Id: stack.html,v 1.1 2009/06/22 16:12:27 kishi Exp kishi $
* Description: HTMLのTABLEタグをパースして、それらの範囲を列挙する
*              入れ子になりうるので、java.util.Stackで対応する
* </pre>
* @author KISHI Yasuhiro
*/

public class TableRegionRetriever {

    private String targetString;
    private final String head1 = "<TABLE>";
    private final String head2 = "<TABLE ";
    private final String head3 = "<TABLE\t";
    private final String head4 = "<TABLE\n";
    private final String head5 = "<TABLE\r\n";
    private final String tail = "</TABLE>";

    /** テーブルの範囲を格納するスタック */
    Stack tableStack = new Stack();

    public TableRegionRetriever ( String targetString ) {
        this.targetString = targetString;
    }

    public java.util.List getRegions( ) {
        LinkedList list = new LinkedList();

        // 最大レングスにあわせる
        int headSize = head5.length();
        ArrayBlockingQueue headQueue = new ArrayBlockingQueue( headSize );

        int tailSize = tail.length();
        ArrayBlockingQueue tailQueue = new ArrayBlockingQueue( tailSize );

        StringReader sr = new StringReader( targetString );
        boolean isStarted = false;

        try {
            int c;
            int from = 0;
            int to = 0;
            int offset = 0;
            while ( ( c = sr.read() ) != -1 ) {

                String headValue = getValueOfQueue( headQueue, headSize, c );
                String tailValue = getValueOfQueue( tailQueue, tailSize, c );

                /* 大文字で比較 */
                if (
                    headValue.toUpperCase().startsWith( head1.toUpperCase() )
                    || headValue.toUpperCase().startsWith( head2.toUpperCase() )
                    || headValue.toUpperCase().startsWith( head3.toUpperCase() )
                    || headValue.toUpperCase().startsWith( head4.toUpperCase() )
                    || headValue.toUpperCase().startsWith( head5.toUpperCase() )
                ) {

                    System.out.println( headValue );

                    isStarted = true;

                    from = offset - headValue.length() + 1;

                    Region region = new Region();
                    // 開始位置だけセットする
                    region.setFrom( from );

                    // スタックに対してpushする
                    tableStack.push( region );
                }

                /* 大文字で比較 */
                if ( tailValue.toUpperCase().equals( tail.toUpperCase() ) ) {

                    System.out.println( tailValue );

                    isStarted = false;

                    to = offset;

                    // スタックからpopする
                    Region region = ( Region ) tableStack.pop();
                    // 終了位置をセットする
                    region.setTo( to );

                    // 得られた範囲をリストに追加
                    int[] intRegion = region.getIntArray();
                    list.add( intRegion );

                    // キューの内容をクリア
                    headQueue.clear();
                    tailQueue.clear();
                }

                offset++;
            }

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

        return list;
    }

    private String getValueOfQueue( ArrayBlockingQueue queue, int size, int c ) {
        if ( queue.size() == size ) {
            // 要素数が最大値に達したら先頭の要素を取り除く
            try {
                queue.take();
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }

        // 要素を追加
        boolean status = queue.offer( ( char ) c );

        Iterator iterator = queue.iterator();
        StringBuffer sb = new StringBuffer();
        while ( iterator.hasNext() ) {
            sb.append( iterator.next() );
        }

        return sb.toString();
    }

    private class Region {
        int[] region;

        public Region() {
            region = new int[ 2 ];
        }
        public void setFrom( int from ) {
            region[ 0 ] = from;
        }
        public void setTo( int to ) {
            region[ 1 ] = to;
        }

        /** 2次元配列のイメージで返す */
        public int[] getIntArray() {
            return region;
        }
    }

    static public void main( String[] args ) {

        StringBuffer sb = new StringBuffer();
        sb.append( "<table> <td></td>" );
        sb.append( "<table>" );
        sb.append( "</table>" );
        sb.append( "</table>" ) ;

        TableRegionRetriever trr = new TableRegionRetriever ( sb.toString() );
        java.util.List list = trr.getRegions( );

        // 得られた範囲のリストを出力
        Iterator iterator = list.iterator();
        while ( iterator.hasNext() ) {
            int[] region = ( int[] ) iterator.next();
            System.out.println( region[ 0 ] + " | " + region[ 1 ] );
        }

        /** 取得したオフセットが正しいかどうかの確認 */
        String targetStr = sb.toString();
        for ( int i = 0; i < targetStr.length(); i++ ) {
            if ( i % 10 == 0 )
                System.out.println();

            System.out.print( i + ": [" + targetStr.charAt( i ) + "] " );
        }
        System.out.println();
    }

}
戻る inserted by FC2 system