8 Stimmen

Wie man Wort für Wort iterieren in Zeichenfolge in C#?

Ich möchte eine Zeichenkette Wort für Wort durchlaufen.

Wenn ich eine Zeichenfolge "incidentno und fintype oder unitno" habe, möchte ich jedes Wort einzeln als "incidentno", "and", "fintype", "or" und "unitno" lesen.

2voto

Maxim Zaslavsky Punkte 17467

Es gibt mehrere Möglichkeiten, dies zu erreichen. Zwei der bequemsten Methoden (meiner Meinung nach) sind:

  • Verwendung von string.Split() um ein Array zu erstellen. Ich würde wahrscheinlich diese Methode verwenden, weil sie am selbsterklärendsten ist.

Beispiel:

string startingSentence = "incidentno and fintype or unitno";
string[] seperatedWords = startingSentence.Split(' ');

Alternativ können Sie auch Folgendes verwenden (so würde ich es machen):

string[] seperatedWords = startingSentence.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);

StringSplitOptions.RemoveEmptyEntries entfernt alle leeren Einträge aus Ihrem Array, die aufgrund von überflüssigen Leerzeichen und anderen kleineren Problemen auftreten können.

Als Nächstes - um die Wörter zu verarbeiten, würden Sie verwenden:

foreach (string word in seperatedWords)
{
//Do something
}
  • Oder, Sie können reguläre Ausdrücke verwenden um dieses Problem zu lösen, da Darin demonstriert (eine Kopie finden Sie unten).

Beispiel:

var regex = new Regex(@"\b[\s,\.-:;]*");
var phrase = "incidentno and fintype or unitno";
var words = regex.Split(phrase).Where(x => !string.IsNullOrEmpty(x));

Für die Verarbeitung können Sie einen ähnlichen Code wie bei der ersten Option verwenden.

foreach (string word in words)
{
//Do something
}

Natürlich gibt es viele Möglichkeiten, dieses Problem zu lösen, aber ich denke, dass diese beiden am einfachsten zu implementieren und zu pflegen sind. Ich würde mich für die erste Option (mit string.Split()) entscheiden, weil Regex manchmal ziemlich verwirrend sein kann, während ein Split in den meisten Fällen korrekt funktioniert.

1voto

ParmesanCodice Punkte 4992

Wie sieht es bei der Verwendung von Split mit der Überprüfung auf leere Einträge aus?

string sentence =  "incidentno and fintype or unitno"
string[] words = sentence.Split(new char[] { ' ', ',' ,';','\t','\n', '\r'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string word in words)
{
// Process
}

EDIT :

Ich kann nicht kommentieren, also poste ich hier, aber das (oben gepostet) funktioniert:

foreach (string word in "incidentno and fintype or unitno".Split(' ')) 
{
   ...
}

Mein Verständnis von foreach ist, dass es zunächst eine GetEnumerator() und die Aufrufe .MoveNext bis false zurückgegeben wird. So wird die .Split nicht bei jeder Iteration neu ausgewertet werden

0voto

public static string[] MyTest(string inword, string regstr)
{
    var regex = new Regex(regstr); 
    var phrase = "incidentno and fintype or unitno";
    var words = regex.Split(phrase);  
    return words;
}

? MyTest("incidentno, und .fintype- oder; :unitno",@"[^ \w +]")

[0]: "incidentno"
[1]: "and"
[2]: "fintype"
[3]: "or"
[4]: "unitno"

0 Stimmen

Hmm ist das eine Antwort?

0voto

Jeroen Vorsselman Punkte 763

Ich möchte einige Informationen zu JDunkerleys Antwort hinzufügen.
Sie können diese Methode leicht zuverlässiger machen, wenn Sie einen String- oder Char-Parameter für die Suche angeben.

public static IEnumerable<string> WordList(this string Text,string Word)
        {
            int cIndex = 0;
            int nIndex;
            while ((nIndex = Text.IndexOf(Word, cIndex + 1)) != -1)
            {
                int sIndex = (cIndex == 0 ? 0 : cIndex + 1);
                yield return Text.Substring(sIndex, nIndex - sIndex);
                cIndex = nIndex;
            }
            yield return Text.Substring(cIndex + 1);
        }

public static IEnumerable<string> WordList(this string Text, char c)
        {
            int cIndex = 0;
            int nIndex;
            while ((nIndex = Text.IndexOf(c, cIndex + 1)) != -1)
            {
                int sIndex = (cIndex == 0 ? 0 : cIndex + 1);
                yield return Text.Substring(sIndex, nIndex - sIndex);
                cIndex = nIndex;
            }
            yield return Text.Substring(cIndex + 1);
        }

-1voto

Roohi Punkte 7496

Ich habe eine String-Prozessor-Klasse geschrieben, die Sie verwenden können.

Beispiel:

metaKeywords = bodyText.Process(prepositions).OrderByDescending().TakeTop().GetWords().AsString();

Klasse:

 public static class StringProcessor
{
    private static List<String> PrepositionList;

    public static string ToNormalString(this string strText)
    {
        if (String.IsNullOrEmpty(strText)) return String.Empty;
        char chNormalKaf = (char)1603;
        char chNormalYah = (char)1610;
        char chNonNormalKaf = (char)1705;
        char chNonNormalYah = (char)1740;
        string result = strText.Replace(chNonNormalKaf, chNormalKaf);
        result = result.Replace(chNonNormalYah, chNormalYah);
        return result;
    }

    public static List<KeyValuePair<String, Int32>> Process(this String bodyText,
        List<String> blackListWords = null,
        int minimumWordLength = 3,
        char splitor = ' ',
        bool perWordIsLowerCase = true)
    {
        string[] btArray = bodyText.ToNormalString().Split(splitor);
        long numberOfWords = btArray.LongLength;
        Dictionary<String, Int32> wordsDic = new Dictionary<String, Int32>(1);
        foreach (string word in btArray)
        {
            if (word != null)
            {
                string lowerWord = word;
                if (perWordIsLowerCase)
                    lowerWord = word.ToLower();
                var normalWord = lowerWord.Replace(".", "").Replace("(", "").Replace(")", "")
                    .Replace("?", "").Replace("!", "").Replace(",", "")
                    .Replace("<br>", "").Replace(":", "").Replace(";", "")
                    .Replace("", "").Replace("-", "").Replace("\n", "").Trim();
                if ((normalWord.Length > minimumWordLength && !normalWord.IsMemberOfBlackListWords(blackListWords)))
                {
                    if (wordsDic.ContainsKey(normalWord))
                    {
                        var cnt = wordsDic[normalWord];
                        wordsDic[normalWord] = ++cnt;
                    }
                    else
                    {
                        wordsDic.Add(normalWord, 1);
                    }
                }
            }
        }
        List<KeyValuePair<String, Int32>> keywords = wordsDic.ToList();
        return keywords;
    }

    public static List<KeyValuePair<String, Int32>> OrderByDescending(this List<KeyValuePair<String, Int32>> list, bool isBasedOnFrequency = true)
    {
        List<KeyValuePair<String, Int32>> result = null;
        if (isBasedOnFrequency)
            result = list.OrderByDescending(q => q.Value).ToList();
        else
            result = list.OrderByDescending(q => q.Key).ToList();
        return result;
    }

    public static List<KeyValuePair<String, Int32>> TakeTop(this List<KeyValuePair<String, Int32>> list, Int32 n = 10)
    {
        List<KeyValuePair<String, Int32>> result = list.Take(n).ToList();
        return result;
    }

    public static List<String> GetWords(this List<KeyValuePair<String, Int32>> list)
    {
        List<String> result = new List<String>();
        foreach (var item in list)
        {
            result.Add(item.Key);
        }
        return result;
    }

    public static List<Int32> GetFrequency(this List<KeyValuePair<String, Int32>> list)
    {
        List<Int32> result = new List<Int32>();
        foreach (var item in list)
        {
            result.Add(item.Value);
        }
        return result;
    }

    public static String AsString<T>(this List<T> list, string seprator = ", ")
    {
        String result = string.Empty;
        foreach (var item in list)
        {
            result += string.Format("{0}{1}", item, seprator);
        }
        return result;
    }

    private static bool IsMemberOfBlackListWords(this String word, List<String> blackListWords)
    {
        bool result = false;
        if (blackListWords == null) return false;
        foreach (var w in blackListWords)
        {
            if (w.ToNormalString().Equals(word))
            {
                result = true;
                break;
            }
        }
        return result;
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X