1

文字列内のタグのシーケンスを探す正規表現を開発しようとしています。たとえば、タグ(NP .*)を少なくとも 1 回 (複数回使用することもできます)、その後に句読点記号 (この場合は a ./.) を付けることができます。de(NP)と the の間に別のタグがある場合./.(以下の例の VP のように)、Matcher は何も見つけてはなりません。問題は、疑問符の後に疑問符を使用しても、式が文字列内の何かに一致するものを.*探し続けることです。)これが私の方法です:

public void myMethod() {
    String input = "(NP first tag) (VP second tag) ./.";
    String regex = "(\\(NP .*?\\)( )?)+" + "\\./\\.";

    Pattern pattern = Pattern.compile("(" + regex + ")");
    Matcher matcher = pattern.matcher(input);

    if (matcher.find()) {
        System.out.println("<S "+matcher.group(0)+">");
    } else {
        System.out.println("sem grupos.");
    }
}

メソッドは引き続き正規表現に一致しますが、そうすべきではありません。「VP」タグは存在しないはずなので、グループが見つからなかったことを知らせる必要があります。この問題は、Java の正規表現が採用している貪欲な戦略に依存していると思います。正規表現で記述されたパターンに対応する文字の組み合わせを見つけようとします。この式をどのように書き直せばよいかわかりません。

ヘルプはありますか?

編集:

1) 私の質問が少しわかりにくいことに気づいたので、わかりやすくするために例を少し変更しました。

2) ありがとう、アーン・ムーア。必要以上のグループを使用していたことに同意しますが、これは のような演算子が原因で発生しました+。不要なグループを切り取ってみました。.*?また、を aに置き換えるという単純なアイデア[^)]*?も素晴らしかったです。私が調整した唯一のことは、 を)使用してシンボルをエスケープしたこと[^\\)]*?です。以下に、使用される最終的な REGEX を示します。

String regex = "(\\(NP [^\\)]*?\\) ?)+\\./\\.";

どうもありがとう!:)

4

1 に答える 1

1

((\(NP .*?\)( )?)+\./\.)コンパイルされたパターンです。

簡素化する:

\(NP .*?\) ?+\./\.未使用のキャプチャ グループを削除します。

それでは、あなたが持っている文字列の例を見てみましょう:

では(NP first tag) (VP second tag) ./..*?一致しfirst tag) (VP second tagます。
では(NP first tag) (VP second tag) (MISC tag that must not be catch) ./.、 に.*?一致しfirst tag) (VP second tag) (MISC tag that must not be catchます。

なんで?つまり、貪欲ではありませんよね?そうですね、でも...

.*?\)マッチングから始まりfirst tag)ます、あなたが欲しいもの。ただし、正規表現の残りの部分は一致に失敗し、正規表現エンジンはそれを可能な答えとしてスローし、探し続けます。

(NP (タグ)) のようなタグにタグがない場合は、パターンを変更できます。\(NP [^)]*?\)

質問で説明した文字列と一致させるには:\(NP [^)]*?\) ?\(VP [^)]*?\) \./\.

Javaエスケープでは になり\\(NP [^)]*?\\) ?\\(VP [^)]*?\\) \./\.ます。

さらに読むために、これに関する理論と実践の詳細をカバーする素晴らしいスタックオーバーフローの質問があります。

于 2012-11-07T05:42:40.787 に答える