共用方式為


HOW TO:查詢包含指定一組字的句子 (LINQ)

更新:2007 年 11 月

這個範例顯示如何在文字檔中尋找含有所指定詞組的句子。雖然這個範例硬式編碼了搜尋詞彙的陣列,但是這類陣列的內容是可以在執行階段動態填入 (Populate) 的。在這個範例中,查詢傳回的句子會包含 "Historically"、"data" 和 "integrated" 這些字。

範例

Class FindSentences

    Shared Sub Main()
        Dim text As String = "Historically, the world of data and the world of objects " & _
        "have not been well integrated. Programmers work in C# or Visual Basic " & _
        "and also in SQL or XQuery. On the one side are concepts such as classes, " & _
        "objects, fields, inheritance, and .NET Framework APIs. On the other side " & _
        "are tables, columns, rows, nodes, and separate languages for dealing with " & _
        "them. Data types often require translation between the two worlds; there are " & _
        "different standard functions. Because the object world has no notion of query, a " & _
        "query can only be represented as a string without compile-time type checking or " & _
        "IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " & _
        "objects in memory is often tedious and error-prone."

        ' Split the text block into an array of sentences.
        Dim sentences As String() = text.Split(New Char() {".", "?", "!"})

        ' Define the search terms. This list could also be dynamically populated at runtime
        Dim wordsToMatch As String() = {"Historically", "data", "integrated"}

        ' Find sentences that contain all the terms in the wordsToMatch array
        ' Note that the number of terms to match is not specified at compile time
        Dim sentenceQuery = From sentence In sentences _
                            Let w = sentence.Split(New Char() {" ", ",", ".", ";", ":"}, _
                                                   StringSplitOptions.RemoveEmptyEntries) _
                            Where w.Distinct().Intersect(wordsToMatch).Count = wordsToMatch.Count() _
                            Select sentence

        ' Execute the query
        For Each str As String In sentenceQuery
            Console.WriteLine(str)
        Next

        ' Keep console window open in debug mode.
        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()
    End Sub

End Class
' Output:
' Historically, the world of data and the world of objects have not been well integrated
class FindSentences
{
    static void Main()
    {
        string text = @"Historically, the world of data and the world of objects " +
        @"have not been well integrated. Programmers work in C# or Visual Basic " +
        @"and also in SQL or XQuery. On the one side are concepts such as classes, " +
        @"objects, fields, inheritance, and .NET Framework APIs. On the other side " +
        @"are tables, columns, rows, nodes, and separate languages for dealing with " +
        @"them. Data types often require translation between the two worlds; there are " +
        @"different standard functions. Because the object world has no notion of query, a " +
        @"query can only be represented as a string without compile-time type checking or " +
        @"IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " +
        @"objects in memory is often tedious and error-prone.";

        // Split the text block into an array of sentences.
        string[] sentences = text.Split(new char[] { '.', '?', '!' });

        // Define the search terms. This list could also be dynamically populated at runtime.
        string[] wordsToMatch = { "Historically", "data", "integrated" };

        // Find sentences that contain all the terms in the wordsToMatch array.
        // Note that the number of terms to match is not specified at compile time.
        var sentenceQuery = from sentence in sentences
                            let w = sentence.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' },
                                                    StringSplitOptions.RemoveEmptyEntries)
                            where w.Distinct().Intersect(wordsToMatch).Count() == wordsToMatch.Count()
                            select sentence;

        // Execute the query. Note that you can explicitly type
        // the iteration variable here even though sentenceQuery
        // was implicitly typed. 
        foreach (string str in sentenceQuery)
        {
            Console.WriteLine(str);
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/* Output:
Historically, the world of data and the world of objects have not been well integrated
*/

查詢的運作方式是先將文字分割成句子,然後再將句子分割成保留每個字的字串陣列。在這些陣列中,Distinct 方法會移除所有重複的字,然後查詢就會對這個文字陣列和 wordstoMatch 陣列執行 Intersect 作業。如果交集的計數與 wordsToMatch 陣列的計數相同,則所有字都可以在文字中找到,因而傳回原始句子。

Split 呼叫中,標點符號會當成分隔符號,以從字串中移除。例如,如果您不這麼做,則您的字串 "Historically," 會與 wordsToMatch 陣列中的 "Historically" 不符。根據來源文字中出現的標點符號類型的不同,您可能需要使用其他分隔符號。

編譯程式碼

  • 建立以 .NET Framework 3.5 版為目標的 Visual Studio 專案。專案預設會含 System.Core.dll 的參考,以及 System.Linq 命名空間 (Namespace) 的 using 指示詞 (C#) 或 Imports 陳述式 (Visual Basic)。請在 C# 專案中,加入 System.IO 命名空間的 using 指示詞。

  • 將此程式碼複製至您的專案。

  • 按 F5 編譯和執行程式。

  • 按任何鍵離開主控台視窗。

請參閱

概念

LINQ 和字串