簡體   English   中英

如何在C#中逐字逐句迭代?

[英]How to word by word iterate in string in C#?

我想逐字逐句地遍歷字符串。

如果我有一個字符串“incidentno和fintype或unitno”,我想逐一閱讀每個單詞“incidentno”,“and”,“fintype”,“or”和“unitno”。

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

即使您的單詞之間有“ .,; tabs and new lines.,; tabs and new lines這也可以正常工作。

稍微扭曲我知道,但您可以將迭代器塊定義為字符串上的擴展方法。 例如

    /// <summary>
    /// Sweep over text
    /// </summary>
    /// <param name="Text"></param>
    /// <returns></returns>
    public static IEnumerable<string> WordList(this string Text)
    {
        int cIndex = 0;
        int nIndex;
        while ((nIndex = Text.IndexOf(' ', 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);
    }

        foreach (string word in "incidentno and fintype or unitno".WordList())
            System.Console.WriteLine("'" + word + "'");

其優點是不為長字符串創建大數組。

使用字符串類的Split方法

string[] words = "incidentno and fintype or unitno".Split(" ");

這將在空格上分開,因此“單詞”將具有[incidentno,and,fintype,or,unitno]

假設單詞總是以空格分隔,您可以使用String.Split()來獲取單詞數組。

有多種方法可以實現這一目標。 兩種最方便的方法(在我看來)是:

  • 使用string.Split()創建一個數組。 我可能會使用這種方法,因為它是最不言自明的。

例:

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

或者,您可以使用(這是我將使用的):

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

StringSplitOptions.RemoveEmptyEntries將從數組中刪除由於額外的空格和其他小問題而可能發生的任何空條目。

接下來 - 處理單詞,您將使用:

foreach (string word in seperatedWords)
{
//Do something
}
  • 或者,您可以使用正則表達式來解決此問題,正如Darin所示 (副本如下)。

例:

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

對於處理,您可以使用與第一個選項類似的代碼。

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

當然,有很多方法可以解決這個問題,但我認為這兩個方法最容易實現和維護。 我會選擇第一個選項(使用string.Split()),因為正則表達式有時會變得非常混亂,而分裂在大多數情況下都會正常運行。

使用拆分時,檢查空條目怎么樣?

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

編輯:

我無法發表評論所以我在這里發帖但是這個(上面發布的)有效:

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

我對foreach的理解是它首先執行GetEnumerator()和calles .MoveNext,直到返回false。 因此,每次迭代都不會重新評估.Split

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,and .fintype-或;:unitno”,@“[^ \\ w +]”)

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

我想向JDunkerley的awnser添加一些信息。
如果您提供要搜索的字符串或char參數,則可以輕松地使此方法更可靠。

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);
        }

我寫了一個字符串處理器類。你可以使用它。

例:

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

類:

 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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM