3

最近 Java で正規表現を使い始めたのですが、奇妙な表現に出くわしました。

この問題は、文字のみで構成され、多くても 1 つの終止符で構成される「単語」を見つけることを要求します。たとえば、次の文字列を入力した場合:

one two. wr7ng not1 three. nope..

エンジンは、一致する単語として one、two、および three を見つけます。この問題の解決策は次のパターンです。

for (String tok : s.split(" ")) {
  if (tok.matches("[a-zA-Z]+//.?")) {
    // code done to record successful match
  }
}

2 つのスラッシュの意味は何ですか? この表現を次の表現と比較しました。

[a-zA-Z]+.?

そして、最後のスロット (ピリオド) で誤って受け入れられた数字のみが見つかりました。違いはこれだけですか?

4

5 に答える 5

5

バックスラッシュではなかったと思いますか?

  "[a-zA-Z]+\\.?"

リテラル文字列内の 2 つのバックスラッシュは、「リテラル文字列に 1 つのバックスラッシュを挿入する」ことを意味すると解釈されます。(慣例として、多くの言語では、バックスラッシュ anychar は「anychar を挿入する」ことを意味します)。

リテラル文字列が正規表現として解釈されると、実際のテキスト

         \.

「「ピリオド」をリテラル文字として一致させる」ことを意味します。

バックスラッシュの「エスケープ文字」がない場合、ほとんどの正規表現エンジンでは「任意の文字に一致」を意味します。

于 2012-05-27T04:53:25.260 に答える
3

そこにタイプミスがあるようです。する必要があります"[a-zA-Z]+\\."

その文字列値が正規表現値になります[a-zA-Z]+\.。バックスラッシュは、.がリテラルピリオドとして扱われる必要があることを示します。これがないと、任意の1文字(数字を含む).に一致する特別な正規表現メタ文字になります。

于 2012-05-27T04:54:43.060 に答える
3

正確なREは次のとおりです。

[a-zA-Z]+\.?

Java を使用してコンパイルするには、もう 1 つのバック スラッシュ \ が必要です。これは、Java 文字列のエスケープ文字を意味します。

"[a-zA-Z]+\\.?"
于 2012-05-27T05:15:21.157 に答える
1

(ドット) を使用する.と、「任意の文字」を意味する正規表現メタ文字として解釈されます。

を使用\.すると、コンパイラ エラーが発生します。不正なエスケープ文字

Usingは、使用する必要がある単純な (ドット) 文字\\.として解釈されます。.

したがって、文字のみを含む単語[a-zA-Z]+の場合、+(プラス) は「1 つ以上」を意味する量指定子です。

単一.(ドット) 文字の場合は、\\.. .ここで、 (ドット) 文字の「最大 1 回」の部分について、?「1 つ以上」を意味する量指定子を使用します。パーツの式は に.なり\\.?ます。

したがって、正規表現は になります[a-zA-Z]+\\.?

于 2012-05-27T05:11:29.700 に答える
1

スラッシュは正規表現では特別な意味を持たないため、"//" は 2 つのスラッシュに一致することを意味します。

それが意味をなさない場合、これはタイプミスか、正規表現を読み間違えたか、誤って転記したかのいずれかです。スラッシュをバックスラッシュに置き換える明らかな「修正」により、次のようになります。

    tok.matches("[a-zA-Z]+\\.?")

これは、「ローマ字とそれに続くオプションの'.'」を一致させることを意味します。文脈上、これは英語の単語の後に終止符/ピリオドが続くことを意味する場合があります。


記録として、"[a-zA-Z]+.?"1 つ以上のローマ字の後に (オプションで) もう 1 つの文字が続くものと一致します。演算子の「熱意」は+、オプションの文字が非文字になることを意味します...どちらかといえば。

于 2012-05-27T04:53:51.973 に答える