i-school - 正規表現を使用してテキストから単語を抽出するユーティリティクラス
 正規表現を使用してテキストから単語を抽出するユーティリティクラスの実装例です。

 今回の場合、「整数のみを除外」した文字列を作成します。
主にテキスト処理や単語の抽出が必要な場面で使用できます。例えば、数式や文章からキーワードを抽出するなどの用途が考えられます。



ユーティリティクラス



using System.Collections.Generic;
using System.Text.RegularExpressions;

/// <summary>
/// テキストから単語を抽出するユーティリティクラスです。
/// </summary>
public static class WordExtractor
{
    // 単語を抽出する正規表現パターン
    private static readonly string WordPattern = @"\b\w+\b";

    /// <summary>
    /// 入力テキストから整数以外の単語を抽出します。
    /// </summary>
    /// <param name="inputText">単語を抽出する対象のテキスト</param>
    /// <returns>整数以外の単語のリスト</returns>
    public static List<string> ExtractWords(string inputText)
    {
        string equationString = inputText;

        // 正規表現を使用して単語を抽出する
        MatchCollection matches = Regex.Matches(equationString, WordPattern);

        // 単語を格納するリスト
        List<string> wordList = new ();

        // マッチした単語をリストに追加
        foreach (Match match in matches)
        {
            string word = match.Value;

      // out で取得した値を利用しない場合には変数宣言ではなくアンダーバー(_)を利用することで明示的に利用しないことを伝えることができる
            if (int.TryParse(word, out int _))
                continue;

            wordList.Add(word);
        }

        return wordList;
    }
}


解説


 与えられたテキストから単語を抽出するためのユーティリティクラスです。
具体的には、正規表現を使用して単語を抽出し、その中から整数として解釈可能なものを除外して単語のリストを作成します。

 ExtractWordsメソッドは、テキスト(inputText引数)を受け取ります。
正規表現パターン @"\b\w+\b" を使用して、テキスト内の単語を検索します。

 マッチした単語をリストに追加しますが、整数として解釈可能な単語は除外します。
結果として、整数以外の単語のリストが返されます

 このコードの流れ全体としては、与えられたテキストから正規表現に一致する単語を抽出し、
その中から整数として解釈可能なものを除外した文字列のリストを作成している、というものです。



 今回利用している MatchCollection クラスは System.Text.RegularExpressions に含まれるものです。
現時点(2024年1月)で MatchCollection クラスは IEnumerable<T> インターフェースを実装しているため、LINQ を活用できます


MicroSoft
System.Text.RegularExpressions.MatchCollection クラス
https://learn.microsoft.com/ja-jp/dotnet/api/syste...


リファクタリング


 LINQ を活用してリファクタリングしましょう。

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

/// <summary>
/// テキストから単語を抽出するユーティリティクラスです。
/// </summary>
public static class WordExtractor
{
    // 単語を抽出する正規表現パターン
    private static readonly string WordPattern = @"\b\w+\b";

    /// <summary>
    /// 入力テキストから整数以外の単語を抽出します。
    /// </summary>
    /// <param name="inputText">単語を抽出する対象のテキスト</param>
    /// <returns>整数以外の単語のリスト</returns>
    public static List<string> ExtractWords(string inputText)
    {
        // 正規表現を使用して単語を抽出し、整数以外の単語をフィルタリング
        MatchCollection matches = Regex.Matches(inputText, WordPattern);

        // MatchCollection は IEnumerable<Match> として扱える
        var words = matches
            .Cast<Match>() // MatchCollection から IEnumerable<Match> に変換(実際には不要ですが、明示的に示しています)
            .Select(match => match.Value)
            .Where(word => !int.TryParse(word, out _))
            .ToList();

        return words;
    }
}


解説


 Regex.Matches は MatchCollection を返します。
このメソッドは、指定された正規表現パターンに一致するテキスト内のすべての部分文字列を検索します。

 Cast<Match>() を使用して、MatchCollection を IEnumerable<Match> に変換しています。
現在の MatchCollection は IEnumerable<T> インターフェースを実装していますので、LINQ 操作が簡単に行えます。
そのため、ここでは明示的に記載していますが、この Cast メソッドは不要です。

 Select は LINQ メソッドで、各 Match オブジェクトから Value プロパティを抽出しています。
Value プロパティには、正規表現によって一致した部分文字列が格納されています。

 Where は LINQ メソッドで、int.TryParse を使用して整数として解釈可能な単語をフィルタリングしています。

 !int.TryParse(word, out _) は整数に変換できない場合に true を返す条件式です。
正規表現に一致する単語のうち、int.TryParseが false を返す(整数として解釈できない)単語だけがリストに含まれ、整数として解釈可能な単語はリストに含まれません。
例えば、"A" や "b" のような文字列はリストに含まれますが、"0" や "8" のような整数として解釈可能な文字列はリストに含まれません。
つまり、整数以外の文字列だけが抽出され、リストに格納されます。

 ToList は LINQ メソッドで、最終的な結果を List<string> に変換しています。
これにより、メソッドの戻り値として操作結果を格納できます。



 処理の内容が理解できれば、さらにリファクタリング可能です。


using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

/// <summary>
/// テキストから単語を抽出するユーティリティクラスです。
/// </summary>
public static class WordExtractor
{
    // 単語を抽出する正規表現パターン
    private static readonly string WordPattern = @"\b\w+\b";

    /// <summary>
    /// 入力テキストから整数以外の単語を抽出します。
    /// </summary>
    /// <param name="inputText">単語を抽出する対象のテキスト</param>
    /// <returns>整数以外の単語のリスト</returns>
    public static List<string> ExtractWords(string inputText)
    {
    // 正規表現を使用して単語を抽出し、整数以外の単語をフィルタリングしてリストに変換して返す
        return Regex.Matches(inputText, WordPattern)
                         .Select(match => match.Value)
                         .Where(word => !int.TryParse(word, out _))
                         .ToList();
    }
}

 Regex.Matches メソッドの戻り値は MatchCollection 型ですが、IEnumerable<T> インターフェースを実装しているため、Cast メソッドは不要です。
そのまま LINQ の Select メソッドや Where メソッドを実行することが可能です。

 最後に ToList して List<string> にキャストしていますので、変数を作成しなくても ToList の戻り値をそのまま return 出来ます。

 このように複数回のリファクタリングを行い、少しずつ理解を深めていくようにしてください。


<抽出対象について>


 今回の実装の場合、正規表現により整数のみを除外しています。

 現在の正規表現パターン @"\b\w+\b" は、単語全体をマッチングさせるものであり、
\w は単語構成文字(英数字およびアンダースコア)を表しています。
この正規表現パターンは整数以外のすべての単語を取り込みます。よって小数点や括弧なども整数以外として抽出されます。

 もし小数点や括弧を除外したい場合は、正規表現パターンを調整する必要があります。

 以下は、整数および小数点を含まない単語を抽出するための正規表現の例です:

private static readonly string pattern = @"\b[^\d.]+\b";

 この正規表現では、\d は数字を表し、. は小数点を表しています。
[^\d.] は数字と小数点以外の文字を表します。したがって、\b[^\d.]+\b は単語全体が数字や小数点を含まない場合に一致します。