ifの条件式を短くする方法の有無

[code]

    if (text[i] == 'a' || text[i] == 'e' || text[i] == 'i' || text[i] == 'o' || text[i] == 'u')
    
[/code]

『`text[i]`が`a`,`e`,`i`,`o`,`u`のどれかである時』  
逐一リピートする表記方法だとカッコ内が長くなるので、短くする方法はそもそも存在しますか？

※入力テキスト内で、if条件の文字を数えるメソッド内で使います。メソッド全体の書き方などまだ練習中なので…。

[code]

    private void NumberOFVowels(string s)
        {
            string text = txtInput.Text;             
            int total = 0;
    
            for (int i = 0; i < text.Length; i++)
            {
                if (text[i] == 'a' || texti] == 'e' || text[i] == 'i' || text[i] == 'o' || text[i] == 'u')
                {
                    total++;
                }
            }
    
        }
    
[/code]




正規表現を使う方法です。[`Regex.IsMatch`のインスタンスメソッド](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.regularexpressions.regex.ismatch?view=netframework-4.7.2#System_Text_RegularExpressions_Regex_IsMatch_System_String_System_Int32_)であれば検索の開始位置を指定できるオーバーロードが用意されています。あくまで検索の開始位置であって文字列の先頭を表すものではないため、正規表現としては`^`ではなく`\G`を使います。「`a`,`e`,`i`,`o`,`u`のどれか」は`[aeiou]`となります。  
総合すると

[code]

    var pattern = new Regex(@"\G[aeiou]");
    if (pattern.IsMatch(text, i))
    
[/code]

となります。

* * *

コメントにも書きましたが、更に外側で何が行われているかによっては、より効率的な記述ができます。例えば`i`がループ変数で「`a`,`e`,`i`,`o`,`u`が最初に出現するインデックス」が必要だとすると

[code]

    var m = Regex.Match(text, "[aeiou]");
    if (m.Success) {
        Console.WriteLine("インデックスは{0}", m.Index);
    } else {
        Console.WriteLine("見つかりませんでした");
    }
    
[/code]

と書けます。まぁこれに関しては[`String.IndexOfAny`](https://docs.microsoft.com/ja-
jp/dotnet/api/system.string.indexofany?view=netframework-4.7.2)を使った方が簡単かもしれませんが。

* * *

追記部分について。  
「文字列`text`に対して`a`,`e`,`i`,`o`,`u`の出現回数を数える」であれば[`Regex.Matches`](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.regularexpressions.regex.matches?view=netframework-4.7.2)でカウントできます。

[code]

    private void NumberOFVowels(string s) {
        int total = Regex.Matches(txtInput.Text, "[aeiou]").Count;
    }
    
[/code]

で済みます。

* * *

C# 7.0で[パターンマッチング](https://learn.microsoft.com/ja-
jp/dotnet/csharp/fundamentals/functional/pattern-matching)が導入され、C#
9.0で[論理パターン](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-
reference/operators/patterns#logical-patterns)が追加されました。これらを使うと次のように書けます。

[code]

    if (text[i] is 'a' or 'e' or 'i' or 'o' or 'u')
    
[/code]

きっとこの答えを望んでおられたのだと思いますが、質問された当時には実現されていませんでした。




正規表現を使う方法です。[`Regex.IsMatch`のインスタンスメソッド](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.regularexpressions.regex.ismatch?view=netframework-4.7.2#System_Text_RegularExpressions_Regex_IsMatch_System_String_System_Int32_)であれば検索の開始位置を指定できるオーバーロードが用意されています。あくまで検索の開始位置であって文字列の先頭を表すものではないため、正規表現としては`^`ではなく`\G`を使います。「`a`,`e`,`i`,`o`,`u`のどれか」は`[aeiou]`となります。  
総合すると

[code]

    var pattern = new Regex(@"\G[aeiou]");
    if (pattern.IsMatch(text, i))
    
[/code]

となります。

* * *

コメントにも書きましたが、更に外側で何が行われているかによっては、より効率的な記述ができます。例えば`i`がループ変数で「`a`,`e`,`i`,`o`,`u`が最初に出現するインデックス」が必要だとすると

[code]

    var m = Regex.Match(text, "[aeiou]");
    if (m.Success) {
        Console.WriteLine("インデックスは{0}", m.Index);
    } else {
        Console.WriteLine("見つかりませんでした");
    }
    
[/code]

と書けます。まぁこれに関しては[`String.IndexOfAny`](https://docs.microsoft.com/ja-
jp/dotnet/api/system.string.indexofany?view=netframework-4.7.2)を使った方が簡単かもしれませんが。

* * *

追記部分について。  
「文字列`text`に対して`a`,`e`,`i`,`o`,`u`の出現回数を数える」であれば[`Regex.Matches`](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.regularexpressions.regex.matches?view=netframework-4.7.2)でカウントできます。

[code]

    private void NumberOFVowels(string s) {
        int total = Regex.Matches(txtInput.Text, "[aeiou]").Count;
    }
    
[/code]

で済みます。

* * *

C# 7.0で[パターンマッチング](https://learn.microsoft.com/ja-
jp/dotnet/csharp/fundamentals/functional/pattern-matching)が導入され、C#
9.0で[論理パターン](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-
reference/operators/patterns#logical-patterns)が追加されました。これらを使うと次のように書けます。

[code]

    if (text[i] is 'a' or 'e' or 'i' or 'o' or 'u')
    
[/code]

きっとこの答えを望んでおられたのだと思いますが、質問された当時には実現されていませんでした。

