2010-12-02 10 views
0
//remove multiple with 
     pat=Pattern.compile("ACCEPT .*?\\.",Pattern.DOTALL); 
     m=pat.matcher(str);  
     while(m.find()) 
     { 

      int start=m.group().indexOf("WITH") +1; 
      String part=m.group().substring(start); 
      part=part.replaceAll("WITH", ""); 
      part=m.group().substring(0, start).concat(part); 

      if(!m.group().equals(part)) 
      { 

       str=m.replaceFirst(part); 

      } 

     } 

これはなぜ無限ループなのでしょうか? m.groupは決してpartと等しくありません。どうしてか分かりません。リセットを試みたが、何もしなかった。Java Matcher and Pattern:なぜこれは永遠に続くのですか

+1

入力文字列は何ですか? –

+0

それは異なります..それはACCEPTで始まり、で終わります。ドット.. – GorillaApe

+2

おそらくあなたはテスト文字列を追加して、あなたのコードに何をしたいのでしょうか? –

答えて

4

私はあなたが達成しようとしているかわかりませんが、バグがここにあります:

if(!m.group().equals(part)) 
{ 
    str=m.replaceFirst(part); 
} 

マッチャはまだstrの元の値で動作しているときは、strを再割り当てされています。文字列は不変です。変数を1か所に再割当てすると、その変数を別の場所に変更しません(参照データ型引数の受け渡しthis page of the Sun java Tutorialを参照)。

さらに奇妙なことが起こっていますが、おそらく私はあなたを正しく理解していません。 コメント内で、文字列がACCEPTで始まり、で終わると言います。ドット。しかし、それはPattern.compile("ACCEPT .*?\\.",Pattern.DOTALL);を探している唯一のもので、あなたは何もキャプチャしていません。それで最初の場所で検索を気にかけないのはなぜですか?私はあなたが入力文字列がそうであることを知っていると思った。

実際に行うべきことは、いくつかのサンプル入力とそれから抽出するデータを投稿することです。そうしないと、誰もあなたを本当に助けることができません。


私はあなたのStringから複数のWITH句を削除したいと思うようです。トマト、パルメザンチーズ 、オリーブのパスタをACCEPT

String test = 
    "ACCEPT pasta " 
     + "WITH tomatoes, parmesan cheese, olives " 
     + "WITH anchovies WITH tuna WITH more olives."; 

System.out.println(
    test.replaceAll(
     "(ACCEPT.*?WITH.*?)(?:\\s*WITH.*)(\\.)", "$1$2" 
    ) 
); 

出力:これははるかに簡単に、このようなものでなければなりません。

ここではパターンがありますが、次のように説明し

final Matcher matcher = 
    Pattern.compile("WITH\\s*", Pattern.DOTALL).matcher(test); 
final StringBuffer sb = new StringBuffer(); 
while(matcher.find()){ 
    matcher.appendReplacement(sb, sb.length() == 0 
     ? matcher.group() 
     : ""); 
} 
matcher.appendTail(sb); 
System.out.println(sb.toString()); 

出力:あなたの更新要件(WITHsを除去するが、引数を保つ)を考えると

(  // start a capturing group 
ACCEPT // search for the literal ACCEPT 
.*?  // search for the shortest possible matching String 
     // (so no other WITH can sneak in) 
WITH // search for the literal WITH 
.*?  // search for the shortest possible matching String 
     // (so no other WITH can sneak in) 
)  // close the capturing group, we'll refer to this 
     // group as $1 or matcher.group(1) 
(?:  // start a non-capturing group 
\\s* // search for optional whitespace 
WITH // search for the literal WITH 
.*  // search for anything, greedily 
)  // close the group, we'll discard this one 
(  // open another capturing group 
\\.  // search for a single period 
)  // close the group, the period is now accessible as $2 

をここで更新ソリューションです:

受け入れパスタトマト、パルメザンチーズ、オリーブは、より多くのオリーブを捕獲します。

+0

あなたはほぼ間違いないと思っています。これは新しいコンパイラ用の古いCOBOLコードを移行するために作ったツールです。あなたの仕事arroundは私が望むように動作しません...私は余分な言葉を削除したい、言い換えれば、オリーブの後にアンチョビtinaより多くのオリーブを印刷する必要があります – GorillaApe

+0

ティナはパスタとうまく落ちるかもしれませんが、 :-)私は秒でアップデートを追加します。 –

関連する問題