3

ある単語グループ内にある特定の単語までの文字列をキャプチャしようとしています。

これらの単語は文字列に何度も出現する可能性があるため、これらの単語の 1 つの最初のインスタンスまでの文字列のみをキャプチャしたいと考えています。

例えば:

単語のグループ: (だった, で, のために)

String = "むかしむかし、穴にキツネがました"; 「むかしむかしそこに」を返します

ありがとうございました

4

4 に答える 4

8

必要なものは先読みと呼ばれます。あなたの状況の正確な正規表現は次のとおりです。

/^.+?(?=(?:was)|(?:in)|(?:for))/

とにかく、^は文字列の先頭に一致します。+?は怠惰な一致(可能な限り短い文字列に一致します)、(?= ...)は「続く」を意味し、(?:...)は非キャプチャグループです-これは必要な場合と不要な場合があります。

ボーナスポイントについては、部分文字列ではなく、単語の境界を使用して単語全体と一致していることを確認する必要があります(「キツネはそうではありませんでした」は「キツネ」を返します)。試合の最後のスペースを殺します:

/^.+?(?=\s*\b(?:was)|(?:in)|(?:for)\b)/

ここで、\ s *は任意の量の空白(まったくないものを含む)に一致し、\bは単語の先頭または末尾に一致します。これはゼロ幅アサーションであり、実際の文字と一致しないことを意味します。

または、Javaの場合:

Pattern p = Pattern.compile("^.+?(?=\\s*\\b(?:was)|(?:in)|(?:for)\\b)");

私はそれがうまくいくと思います。私はそれを使用していませんが、ドキュメントによると、その正確な文字列は機能するはずです。すべての円記号をエスケープする必要がありました。

編集

1年以上経った今、私はここにいます。上記の正規表現は、当時思っていたとおりに機能しないことに気づきました。交互は最低ではなく最高の優先順位を持っているので、このパターンはより正確です。

/^.+?(?=\s*\b(?:was|in|for)\b)/

この新しい正規表現を私の古い正規表現と比較してください。 さらに、将来の旅行者は、そのようなブレーカーワードが存在しない場合は、文字列全体をキャプチャすることをお勧めします。サイズについては、これを試してください。

/^(?:(?!\s*\b(?:was|in|for)\b).)*/

これはネガティブ先読みを使用します(パターンに失敗する一致をアサートします)。それはおそらく遅いですが、それでも仕事をします。 ここで実際の動作を確認してください

于 2012-08-09T21:33:26.180 に答える
5

このコードを使用して、終了単語の前の文字列をキャプチャできます。

Pattern p = Pattern.compile("^(.*?)((\\b(was|in|for)\\b)|$)");
String s = "Once upon a time there was a fox in a hole";
Matcher m = p.matcher(s);
if (m.find()) {
    System.out.println(m.group(1));
}

このコードは、次の出力を生成します (リンク)。

Once upon a time there

この表現がどのように機能するかは次のとおりです。 は、(\\b(was|in|for)\\b)「単語の境界に現れる場合、内側の括弧にリストされている単語のいずれか」を意味します。すぐ外側の表現$は、ソースに終了単語がまったく表示されない場合でも、何かをキャプチャするために使用できます。

于 2012-08-09T21:38:08.667 に答える
3

これを処理する非常に簡単な方法はsplit、正規表現を含む文字列だけを使用し、最初に返されたものを保持することです。

String str = "Once upon a time there was a fox in a hole";
String match = str.split("(was|in|for)")[0];

// match = "Once upon a time there "

この例では、最初に一致した単語のmatchの文字列の最初の部分が含まれるか、単語が見つからなかった文字列の場合は文字列全体が含まれます。

于 2012-08-09T21:38:37.890 に答える
2
String s = "Once upon a time there was a fox in the hole";
String[] taboo = {"was", "in", "for"} ;
for (int i = 0; i < taboo.length; i++){
    if (s.indexOf(taboo[i]) > -1 ){
        s=s.substring(0, s.indexOf(taboo[i])) ;
    }
}
out.print(s);

私のコンピューターで動作します..

于 2012-08-09T21:37:16.517 に答える