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();
}
}
戻る