1

私の目標は、テキスト内の特定のパターンに一致するものをすべて見つけることです。私のパターンは次のとおりです。

h.*o

これは、で始まり、その間に任意の数の文字がある(ゼロでもある)テキストを検索していることを意味し'h'ます'o'

私の理解では、メソッドMatches()は説明に従って複数の一致を提供するということでした ( MSDNを参照)。

const string input = "hello hllo helo";
Regex regex = new Regex("h.*o");

var result = regex.Matches(input);
foreach (Match match in result)
{
    Console.WriteLine(match.Value);
}

私の期待は次のとおりです。

1. "hello"
2. "hllo"
3. "helo"
4. "hello hllo"
5. "hello hllo helo"

驚いたことに、返された一致には 1 つの文字列 (入力文字列全体) しか含まれていません。

"hello hllo helo"

質問:

  1. どちらが間違っていますか: 私の期待、私の正規表現、またはクラスの使用法?
  2. 私の例に示すように結果を達成するにはどうすればよいですか?

前もって感謝します。

4

2 に答える 2

3

貪欲*です- できるだけ多くの文字を一致させようとします。疑問符を付けることで拒否することもできますが、次のように、文字が一致する場合はリストから除外することをお勧めします。o.

h[^o]*o

これは、貪欲と消極的の非常に良い説明へのリンクです。

于 2012-05-13T15:05:04.163 に答える
2

*貪欲であるという事実に加えて、このMatchesメソッドは重複しない一致のみを検索します。つまり、最後の試合が中断した位置から開始して、後続の各試合を検索します。MSDNライブラリから:

通常、正規表現エンジンは、前の一致が中断したところから正確に次の一致の検索を開始します。

したがって、を使用した場合でも、の代わりに使用した*?場合でも、「hello」、「hllo」、および「helo」のみが検出されます。h[^o]*o*

指定されたパターンに一致する可能性のあるすべてRegexのサブストリングを効率的に見つけるための組み込みメソッドがあるかどうかはわかりませんが、可能性のあるすべてのサブストリングを自分でループして、それぞれが一致するかどうかを確認できます。

const string input = "hello hllo helo";
Regex regex = new Regex("^h.*o$");

for (int startIndex = 0; startIndex < input.Length - 1; startIndex++)
{
    for (int endIndex = startIndex + 1; endIndex <= input.Length; endIndex++)
    {
        string substring = input.Substring(startIndex, endIndex - startIndex);
        if (regex.IsMatch(substring))
            Console.WriteLine(substring);
    }
}

出力:

hello
hello hllo
hello hllo helo
hllo
hllo helo
helo

の部分文字列だけでなく、全体と一致するように正規表現にとを追加^したことに注意してください。$substringsubstring

于 2012-05-13T15:12:01.600 に答える