Partager via


Comment : rechercher des phrases qui contiennent un groupe de mots spécifié (LINQ)

Cet exemple montre comment rechercher des phrases dans un fichier texte qui contient des correspondances pour chaque mot d'un groupe de mots spécifié. Même si le tableau des termes de recherche est codé en dur dans cet exemple, il pourrait également être rempli dynamiquement au moment de l'exécution. Dans cet exemple, la requête retourne les phrases qui contiennent les mots « Historically », « data » et « integrated ».

Exemple

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
*/

La requête fonctionne en fractionnant d'abord le texte en phrases, puis en fractionnant les phrases en un tableau de chaînes qui contient chaque mot. Pour chacun de ces tableaux, la méthode Distinct``1 supprime tous les doublons, puis la requête effectue une opération Intersect``1 sur le tableau de mots et le tableau wordstoMatch. Si le nombre de l'intersection est le même que le nombre du tableau wordsToMatch, tous les mots ont été trouvés dans les mots et la phrase d'origine est retournée.

Dans l'appel à Split, les signes de ponctuation sont utilisés comme séparateurs pour les supprimer de la chaîne. Si vous ne le faites pas, vous pouvez par exemple obtenir une chaîne « Historically » qui ne correspondrait pas à « Historically » dans le tableau wordsToMatch. Vous devrez peut-être utiliser des séparateurs supplémentaires, en fonction des types de ponctuations trouvés dans le texte source.

Compilation du code

  • Créez un projet Visual Studio qui cible .NET Framework version 3.5. Par défaut, le projet possède une référence à System.Core.dll et une directive using (C#) ou une instruction Imports (Visual Basic) pour l'espace de noms System.Linq. Dans les projets C#, ajoutez une directive using pour l'espace de noms System.IO.

  • Copiez ce code dans votre projet.

  • Appuyez sur F5 pour compiler et exécuter le programme.

  • Appuyez sur une touche pour quitter la fenêtre de console.

Voir aussi

Concepts

LINQ et chaînes