7

初投稿です。

まず、パターン マッチャーと文字列分割の両方の使用方法を知っています。私の質問は、私の例で使用するのに最適なものとその理由です。または、より良い代替案の提案。

タスク: 未知の文字列内の 2 つの既知の正規表現の間で未知の NOUN を抽出する必要があります。

私の解決策:名詞の開始と終了(正規表現1と2から)と部分文字列を取得して、名詞を抽出します。

String line = "unknownXoooXNOUNXccccccXunknown";
int goal = 12 ;
String regexp1 = "Xo+X";
String regexp2 = "Xc+X";
  1. 最初の正規表現の後にインデックス位置を見つける必要があります。
  2. 2 番目の正規表現の前にインデックス位置を見つける必要があります。

A)パターンマッチャーを使用できます

    Pattern p = Pattern.compile(regexp1);
    Matcher m = p.matcher(line);
    if (m.find()) {
        int afterRegex1 = m.end();
    } else {
        throw new IllegalArgumentException();
        //TODO Exception Management;
    }

B) 文字列分割を使用できます

    String[] split = line.split(regex1,2);
    if (split.length != 2) {
        throw new UnsupportedOperationException();
        //TODO Exception Management;
    }
    int afterRegex1 = line.indexOf(split[1]);

どのアプローチを使用する必要があり、その理由は? 時間とメモリのどちらがより効率的かはわかりません。両方とも、私にとっては十分に読みやすいものです。

4

4 に答える 4

5

私は次のようにします:

String line = "unknownXoooXNOUNXccccccXunknown";
String regex = "Xo+X(.*?)Xc+X";

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(line);
if (m.find()) {
   String noun = m.group(1);
}

(.*?)、NOUN reluctantの内部一致を作成するために使用されます。これにより、文字列の未知の部分に終了パターンが再び現れるケースから保護されます。

編集

これが機能するのは、 がキャプチャ グループ(.*?)を定義するためです。このようなグループはパターンで 1 つしか定義されていないため、インデックス 1 ( へのパラメーター) を取得します。これらのグループは、1 から開始して左から右にインデックス付けされます。パターンが次のように定義されている場合m.group(1)

String regex = "(Xo+X)(.*?)(Xc+X)";

次に、次のような3 つのキャプチャ グループがあります。

m.group(1); // yields "XoooX"
m.group(2); // yields "NOUN"
m.group(3); // yields "XccccccX"

グループ 0があります、それはパターン全体に一致し、これと同等です

m.group(); // yields "XoooXNOUNXccccccX"

Matcherソース文字列内のパターンの開始位置と終了位置を取得する方法など、 でできることの詳細については、 Matcher JavaDocsを参照してください。

于 2013-10-16T17:34:06.953 に答える
2

ユニークなオカレンスを取得したいようです。このためには、単純に

input.replaceAll(".*Xo+X(.*)Xc+X.*", "$1")

効率のために、Pattern.matcher(input).replaceAll代わりに使用してください。

入力に改行が含まれている場合は、Pattern.DOTALLまたはs修飾子を使用します。


split を使用したい場合は、Guava の の使用を検討してSplitterください。Patternより正常に動作し、速度に適した a も受け入れます。

于 2013-10-16T17:36:15.287 に答える
0

本当に場所が必要な場合は、次のようにできます。

String line = "unknownXoooXNOUNXccccccXunknown";
String regexp1 = "Xo+X";
String regexp2 = "Xc+X";

Matcher m=Pattern.compile(regexp1).matcher(line);
if(m.find())
{
  int start=m.end();
  if(m.usePattern(Pattern.compile(regexp2)).find())
  {
    final int end = m.start();
    System.out.println("from "+start+" to "+end+" is "+line.substring(start, end));
  }
}

しかし、中間の単語だけが必要な場合は、Ian McLaird が示した方法をお勧めします。

于 2013-10-16T17:38:44.333 に答える