2017-12-28 5 views
2

Ich versuche, um herauszufinden, was für eine richtige Art und Weise ist sub-String in anderer Zeichenfolge zu suchen gleich Ausgänge für Content-Beispiel zu erhalten:Suche nach Teilzeichen in Zeichenfolge mit spezifischen Bedingungen

hello how are you 

mit wahren für Eingänge :

hey hello how are you ok 
how are you 
are you 

und falsch für diese:

you 
how you are ok you 
howareyou 
howok 
how you 
hey hello 

ich mit der gleichen Phrase oder einen Teil der Phrase con wahren wollen in einer Zeichenfolge, aber nicht einzelne Wörter oder Wörter in einer anderen Sequenz. Auf diese Weise es gilt für alle mit (aList.Any(input.Contains)) und falsch für alle mit (aList.Contains(input)):

 List<string> aList = new List<string>() { 
               "hey hello how are you ok", 
               "how are you", 
               "are you", 
               "you", 
               "how you are ok you", 
               "howareyou", 
               "howok", 
               "how you", 
               "hey hello" }; 

      string input = "hello how are you"; 

      foreach (string a in aList) 
      { 
       if (a.Any(input.Contains)) 
       { 
        Console.WriteLine(a + " - true"); 
       } 
       else 
       { 
        Console.WriteLine(a + " - false"); 
       } 
      } 

      Console.WriteLine("__\n\r"); 

      foreach (string a in aList) 
      { 
       if (a.Contains(input)) 
       { 
        Console.WriteLine(a + " - true"); 
       } 
       else 
       { 
        Console.WriteLine(a + " - false"); 
       } 
      } 
+2

Hallo, einen richtigen Namen gibt zur Liste. –

+1

Wenn Sie in Worten beschreiben können, was ein wahres und was ein falsches Ergebnis darstellt, dann wäre es möglich. Andernfalls müssen Sie alle wahren und falschen Möglichkeiten auflisten und vergleichen. –

+3

Was ist deine Argumentation, um "wahr" für "bist du", aber "falsch" für "du" zurückzugeben? – Greggz

Antwort

2

kam ich mit dieser Lösung:

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

public class Program 
{ 
    public static void Main() 
    { 
     List<string> aList = new List<string>() 
     {"hey hello how are you ok", "how are you", "are you", "you", "how you are ok you", "howareyou", "howok", "how you", "hey hello"}; 


     var input = "hello how are you"; 

     // build matcher 
     string[] chunks = input.Split(' '); 
     string matcher = ""; 
     for (int i = chunks.Length, j = 0; i > 1; i--, j++){ 
      var matcherPart = new string [i]; 
      Array.Copy(chunks, j, matcherPart, 0, i); 
      matcher += "("+String.Join(@"+\s+", matcherPart) + ")"; 
     } 
     matcher = matcher.Replace(")(", ")|("); 

     // Console.WriteLine(matcher); 
     //(hello+\s+how+\s+are+\s+you)|(how+\s+are+\s+you)|(are+\s+you)"; 


     foreach (string a in aList) 
     { 
      Regex r = new Regex(matcher, RegexOptions.IgnoreCase); 
      Match m = r.Match(a); 
      Group g = m.Groups[0]; 
      Console.WriteLine(a + " - " + (g.Captures.Count > 0)); 
     } 

     /* 

     hey hello how are you ok - True 
     how are you - True 
     are you - True 
     you - False 
     how you are ok you - False 
     howareyou - False 
     howok - False 
     how you - False 
     hey hello - False 

     */ 
    } 
} 

Der Build-Matcher Teil regexp mit möglichen Kombinationen erzeugt, das heißt diese Zeichenfolge a b c d dazu umgewandelt wird: (a+b+c+d)|(b+c+d)|(c+d). Damit können Sie Ihre Listenwerte problemlos durchlaufen und regexp anwenden. Die g.Captures.Count sagt Ihnen, ob der Artikel Ihrer Liste zu Ihren Mustern passt oder nicht.

+0

Eine kleine Erklärung, warum dies das Problem löst, würde die Qualität Ihrer Antwort wirklich verbessern –

+0

Nun, der 'Build Matcher' Teil erzeugt Regexp mit möglichen Kombinationen, dh dieser String' abcd' wird transformiert zu diesem: "(a) | (b) | (c) | (d)". Damit können Sie Ihre Listenwerte problemlos durchlaufen und regexp anwenden. Der 'g.Captures.Count' sagt dir, ob dein Item mit deinen Pattern übereinstimmt oder nicht. – Andy

+0

Klingt gut. Warum fügst du es nicht zur Antwort hinzu? Wir alle sind hier, um zu lernen und Erklärungen sind der Schlüssel dazu. Sie sehen es an der Anzahl der Stimmen bei Ihren Antworten. Prost Mate –

1

Dies soll jetzt arbeiten, wie Sie nichts anderes specifiy haben. Mindestens 2 Wörter vorhanden return true

string [] array = input.Split(' '); 

    foreach(string a in list) 
    { 
     bool yes = false; 
     for(int i = 0; i < array.Length-1; ++i){ 
      string test = array[i] + " " + array[i+1]; 
      if(a.Contains(test)){ 
       yes = true; 
      } 
     } 

     Console.WriteLine(yes); 
    } 
+0

@terry War etwas falsch mit meinem Code? – Greggz

+0

ja und auch dieses mit gewünschtem Ergebnis – terry

1

Ich würde dieses Problem in 2 Schritte teilen.

1) Split die Eingabe durch ' ' (Raum) und eine Sammlung aller möglichen subphrases machen, die angepasst werden können:

string input = "hello how are you"; 

string[] inputParts = input.Split(' '); 

List<string> subphrases = new List<string>(); 

for (int i = 0; i < inputParts.Length-1; i++) 
{ 
    subphrases.Add(string.Join(" ", inputParts.Skip(i))); 
} 

2) Nehmen Sie von Ihrem Korpus/aList nur die Elemente Where ein Element ContainsAny der Elemente in Ihrer subphrases Sammlung:

List<string> all_TRUE_Matches = aList.Where(
        corpusItem => subphrases.Any(sub => corpusItem.Contains(sub))).ToList(); 

die Reihenfolge, in der Code unterscheidet sich f Aus meinem Satz. Any gibt true für jede corpusItem in aList zurück, die Contains mindestens 1 Element aus der subphrases Sammlung enthält. (Ich hoffe, dass dies deutlicher ist;))

Um eine Liste von FALSE Matches bekommen einfach die Any Bedingung negieren:

List<string> all_FALSE_Matches = aList.Where(
        corpusItem => !subphrases.Any(sub => corpusItem.Contains(sub))).ToList(); 
+1

hallo, ja das ist eine andere funktionierende Lösung – terry