0

私が扱っている問題は、その語尾が特定のリストにある場合、語尾を削除する必要があることです。

つまり、リストは次のとおりです。

{ical, ic,ion,ogy} //the actual list is a handful of elements (almost ~20)

私がする必要があるのは、次のような文に出くわしたときです。

Hello world, this sentence is magic. Because we will talk about Biology.

次のように削減されます。

Hello world, this sentence is **mag** . Because we will talk about **Biol** .

これを行う最も簡単な方法は、文中の単語を繰り返し処理し、各語尾がリスト内の要素と一致するかどうかを確認することですが、これには非常にコストがかかります。

上記を達成するためのより簡単な方法はありますか?

***** また *****

単一の大きな REGEX でこれを行うことができます。

(?<=([a-zA-Z]))(ic|ical|ics|raphy|raphic|raphical|ion|ions|ional|ive|ivity|ity|ities|ische|ischen|ischer|isches|ogy|ogic|ogical|omy|omic|omics|omical)(?=(\b))
4

3 に答える 3

4

簡単なアプローチ:

入力文字列の正規表現を作成し、その正規表現のすべての出現箇所を何も置き換えません。

正規表現は次の形式になります。

(a|b|c)\\b

(a|b|c)abまたはに一致しcます。
\\b単語の終わりを示す単語境界です。

コード:

String[] arr = {"ical", "ic", "ion", "ogy"};
String input = "Hello world, this sentence is magic. Because we will talk about Biology.";
String regex = "(" + arr[0];
for (String s: arr)
   regex += "|" + s; // using Pattern.quote(s) instead of s here would be safer
regex += ")\\b";
input = input.replaceAll(regex, "");
System.out.println(input);

版画:

Hello world, this sentence is mag. Because we will talk about Biol.

かなり複雑なアプローチ:

サフィックスのトライを作成しますが、逆にします。

裏側から紐を加工します。

単語の始まりを見つけたら、トライを調べて次の文字を探し、トライで一致が見つかったらそれらを切り捨てます。

これを効率的に行うには、最後にStringBuilderandを使用します。StringBuilder.reverse()

例:

与えられた:

ical, ic, ion, ogy

トライは次のようになります。

          .
         /|\
      y // \\ l
       /n| |c\
      .  . .  .
     g| o| |i |a
      .  . X  .
     o| i|    |c
      X  X    .
              |i
              X

(Xは終端ノード (接尾辞の終わり)、.は非終端ノード)

入力:

John Biology.

逆に処理...

プロセス:"."

言葉ではなく、出力に追加するだけです。

出力 ="."

プロセス:"Biology"

ルートにはy子があるので、そのノードに移動します。
そのノードにはg子があるので、先に進みます。
そのノードにはo子があるので、先に進みます。次に、終端ノードに到達したので、処理された文字を破棄し、残りの単語を出力します。

出力:".loiB"

プロセス:" "

言葉ではなく、出力に追加するだけです。

出力 =".loiB "

プロセス:"John"

ルートにはn子があるので、そのノードに移動します。
そのノードには子がないhので、停止して、処理された文字を残りの単語とともに出力します (つまり、単語全体を出力します)。

出力 =".loiB nhoJ"

逆にすると、次のようになります。"John Biol."

于 2013-10-14T13:59:33.473 に答える
0

チェックしたいエンディングの数が限られている場合は、エンディングごとに正規表現を生成できます。これにより、エンディングが発生したかどうかを効率的にチェックできます。文を分割する必要はなく、1 行で置換できます。

悲しいことに、私の Java Regex の知識は、必要な正規表現をその場で構築できるほど十分ではありませんが、ご覧になることができます。しかし、そこには多くの優れたチュートリアルがあります。

于 2013-10-14T13:59:14.723 に答える