- PR -

jakarta OROについて

1
投稿者投稿内容
banboo
大ベテラン
会議室デビュー日: 2003/12/05
投稿数: 210
投稿日時: 2003-12-05 01:00
jakarta OROについて質問が御座います。

<A><B><C>X1</C><D>X2</D></B><B><C>X3</C><D>X4</D></B><B><C>X5</C><D>X6</D></B></A>

という内容のauto5.txtを

<A><B><C>
</C><D>
</D></B><B><C>
</C><D>
</D></B><B><C>
</C><D>
</D></B></A>

のように、タグ以外の文字部分で区切りたいのですが、下記のプログラムを実行すると

X1

X2



X3

X4



X5

X6

と改行が入ってしまいます。


質問1 上記のように改行が入ってしまうのは何故か?

私はパターンマッチの部分を
reg.split(e, "/<.*?>/", buf);
と書いております。perlだと?は最小マッチを表すので

reg.split(e, "/<.*?>/", buf);
はタグの最小部分、つまり、<A>とか<B>にマッチするように
感じたのですが、結果をみるとどうも
<A><B><C>のいちばん外側の<>にマッチしているようです。

質問2 タグの最小部分、つまり、<A>とか<B>にマッチするように
するにはどう書けばよいのか?

質問3reg.split(e, "/<.*>/", buf);
としたら、マッチする部分がありませんでした。
私は、
「.」が任意の文字、そして「*」によって
繰返しを表せるので、<A>とか<B>にマッチするだろうと
思ったのですが。。。
どこか間違っている
という事でしょうか?


どなたか私の行いたい事、上記の問題点をご存知のかたが
いらっしゃいましたらご教授御願いいたします。

import java.io.*;
import java.util.Vector;

import org.apache.oro.text.perl.*;
import org.apache.oro.text.regex.PatternMatcherInput;

public class SplitString {
public static void main(String args[]){


try {


File file = new File("auto5.txt");

BufferedReader in = new BufferedReader(new FileReader(file));
String buf = null;
Perl5Util reg = new Perl5Util();

//PatternMatcherInput pmi = new PatternMatcherInput(buf);

Vector e = new Vector();

while((buf = in.readLine())!=null){

System.out.println("buf = " + buf);



//PatternMatcherInput pmi = new PatternMatcherInput(buf);


//reg.split(e, "/^(<.*?>)/", buf);
//reg.split(e, "/^<.*?>/", buf);
//reg.split(e, "/\b/", buf);
reg.split(e, "/<.*?>/", buf);

for(int i=0;i<e.size();i++){
String str=(String)e.get(i);
System.out.println(str);
}



}


} catch (Exception e){
System.out.println(e);
}

}
}

Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-12-05 11:01
はじめまして、Wataと申します。

banbooさんの書き込み (2003-12-05 01:00) の回答:
>質問1 上記のように改行が入ってしまうのは何故か?
コード:
	  for(int i=0;i<e.size();i++){
		  String str=(String)e.get(i);
		  System.out.println(str);
	  }


この様にprintlnで出力しているからです。
その部分を単純に、
コード:
	  System.out.println(e);


と置き換えると、出力は
[, , , X1, , X2, , , , X3, , X4, , , , X5, , X6, , , ]
となります。つまり<A>と<B>の間の空文字列("")が出力され、
println()で改行されているのです。


>質問2 タグの最小部分、つまり、<A>とか<B>にマッチするようにするにはどう書けばよいのか?
前述のように、splitの結果は
[, , , X1, , X2, , , , X3, , X4, , , , X5, , X6, , , ]
です。つまり、先頭の<A>と<B>の間の空文字列が適切に取り出されています。
よって、パターンはちゃんと最小マッチしています。

> 質問3 reg.split(e, "/<.*>/", buf);としたら、マッチする部分がありませんでした。
splitに指定するパターンは区切り文字列のパターンですよ。
この場合、先頭の<A>から末尾の</A>まで文字列全体がマッチします。
つまり、マッチ箇所の間は無いので、eには何も格納されません。

それから、取り出したいのはXMLのテキスト部分ではなく、タグの部分なんですよね。
だったら、splitを使うより、繰り返しマッチさせて、マッチ箇所を取り出したほうが
いいのではないでしょうか?
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-05 11:53
引用:

私はパターンマッチの部分を
reg.split(e, "/<.*?>/", buf);
と書いております。perlだと?は最小マッチを表すので


すみません。私もPerlの正規表現は結構分かってるつもりですが、こんな書き方ってありましたっけ?
Perlって基本的に最長一致ですよね?

まあともあれ、Wataさんがおっしゃるように「splitを使うより繰り返しマッチさせて、マッチ箇所を
取り出したほうがいい」と思います。

コード:
String str = "<A><B><C>X1</C><D>X2</D></B><B><C>X3</C><D>X4</D></B><B><C>X5</C><D>X6</D></B></A>";
Perl5Util reg = new Perl5Util();
if ( reg.match("/>([^<]+)</g", str) ){
    for ( int i=0; i<reg.groups(); i++ ){
        String ptn = reg.group(i);
        System.out.println(ptn);
    }
}


とかでどうですか?
このコードはテスト実行してないので、うまくいかなかったらすみません。
mikan
ベテラン
会議室デビュー日: 2002/08/19
投稿数: 58
投稿日時: 2003-12-06 14:51
引用:
すみません。私もPerlの正規表現は結構分かってるつもりですが、こんな書き方ってありましたっけ?
Perlって基本的に最長一致ですよね?



? を付けると最短一致にできますよ。

とりあえず、このあたりで。
http://www5a.biglobe.ne.jp/~n_rieko/perl/8.htm
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-07 23:29
引用:

? を付けると最短一致にできますよ。


なるほど。
してみると、今回のケースはOROがPerl5の正規表現全てを実装してるわけではないということですかね。
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-12-08 09:30
引用:

おばけさんの書き込み (2003-12-07 23:29) より:
なるほど。
してみると、今回のケースはOROがPerl5の正規表現全てを実装してるわけではないということですかね。


? OROは、+?, *?などの最小一致はちゃんと実装されてますよ。
ちなみにjava.util.regexの正規表現でも使えます。
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-08 12:29
引用:

? OROは、+?, *?などの最小一致はちゃんと実装されてますよ。


おお、すみません、Wataさんの書き込みをちゃんと読んでませんでした。
splitで区切り文字列のところに正規表現を指定していたのが問題だったのですね。
勘違いしていました。
1

スキルアップ/キャリアアップ(JOB@IT)