如何将文本分割成单词

本文关键字:单词 分割 文本 | 更新日期: 2023-09-27 18:15:00

如何将文本分割成单词?

示例文本:

"哦,你没办法,"猫说,"我们这儿都疯了。我疯了。你疯了。"

这一行的单词是:

  1. 我们
  2. 疯狂
  3. 这里的
  4. 疯狂
  5. 疯狂

如何将文本分割成单词

用空格分割文本,然后修改标点符号。

var text = "'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.'";
var punctuation = text.Where(Char.IsPunctuation).Distinct().ToArray();
var words = text.Split().Select(x => x.Trim(punctuation));

首先,删除所有特殊字符:

var fixedInput = Regex.Replace(input, "[^a-zA-Z0-9% ._]", string.Empty);
// This regex doesn't support apostrophe so the extension method is better

然后拆分:

var split = fixedInput.Split(' ');

对于一个简单的c#解决方案来删除特殊字符(你可以很容易地改变),添加这个扩展方法(我添加了对撇号的支持):

public static string RemoveSpecialCharacters(this string str) {
   var sb = new StringBuilder();
   foreach (char c in str) {
      if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '''' || c == ' ') {
         sb.Append(c);
      }
   }
   return sb.ToString();
}

然后像这样使用:

var words = input.RemoveSpecialCharacters().Split(' ');

你会惊讶地发现这个扩展方法非常有效(肯定比正则表达式更有效),所以我建议你使用它;)

我同意这是一个只有英文的方法,但要使它与Unicode兼容,你所要做的就是替换:

(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')

:

char.IsLetter(c)

它支持Unicode, .Net还为各种情况提供char.IsSymbolchar.IsLetterOrDigit

只是在@Adam Fridental的答案上添加一个变体,这是非常好的,你可以尝试这个正则表达式:

var text = "'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.'";
var matches = Regex.Matches(text, @"'w+[^'s]*'w+|'w");
foreach (Match match in matches) {
    var word = match.Value;
}

我相信这是最短的RegEx,可以得到所有的单词

'w+[^'s]*'w+|'w

如果您不想使用Regex对象,您可以这样做…

string mystring="Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.";
List<string> words=mystring.Replace(",","").Replace(":","").Replace(".","").Split(" ").ToList();

你仍然需要处理"that "结尾的撇号

这是一个解决方案,我不使用任何辅助类或方法。

        public static List<string> ExtractChars(string inputString) {
            var result = new List<string>();
            int startIndex = -1;
            for (int i = 0; i < inputString.Length; i++) {
                var character = inputString[i];
                if ((character >= 'a' && character <= 'z') ||
                    (character >= 'A' && character <= 'Z')) {
                    if (startIndex == -1) {
                        startIndex = i;
                    }
                    if (i == inputString.Length - 1) {
                        result.Add(GetString(inputString, startIndex, i));
                    }
                    continue;
                }
                if (startIndex != -1) {
                    result.Add(GetString(inputString, startIndex, i - 1));
                    startIndex = -1;
                }
            }
            return result;
        }
        public static string GetString(string inputString, int startIndex, int endIndex) {
            string result = "";
            for (int i = startIndex; i <= endIndex; i++) {
                result += inputString[i];
            }
            return result;
        }

如果你想使用"for循环"来检查每个字符和保存所有标点在输入字符串我已经创建了这个类。方法GetSplitSentence()返回一个SentenceSplitResult的列表。在这个列表中保存了所有的单词和标点符号。数字。保存的每个标点符号或数字都是列表中的一个项目。sentenceSplitResult。isAWord用于检查是否为单词。[对不起我的英语]

public class SentenceSplitResult
{
    public string word;
    public bool isAWord;
}
public class StringsHelper
{
    private readonly List<SentenceSplitResult> outputList = new List<SentenceSplitResult>();
    private readonly string input;
    public StringsHelper(string input)
    {
        this.input = input;
    }
    public List<SentenceSplitResult> GetSplitSentence()
    {
        StringBuilder sb = new StringBuilder();
        try
        {
            if (String.IsNullOrEmpty(input)) {
                Logger.Log(new ArgumentNullException(), "GetSplitSentence - input is null or empy");
                return outputList;                    
            }
            bool isAletter = IsAValidLetter(input[0]);
            // Each char i checked if is a part of a word.
            // If is YES > I can store the char for later
            // IF is NO > I Save the word (if exist) and then save the punctuation
            foreach (var _char in input)
            {
                isAletter = IsAValidLetter(_char);
                if (isAletter == true)
                {
                    sb.Append(_char);
                }
                else
                {
                    SaveWord(sb.ToString());
                    sb.Clear();
                    SaveANotWord(_char);                        
                }
            }
            SaveWord(sb.ToString());
        }
        catch (Exception ex)
        {
            Logger.Log(ex);
        }
        return outputList;
    }
    private static bool IsAValidLetter(char _char)
    {
        if ((Char.IsPunctuation(_char) == true) || (_char == ' ') || (Char.IsNumber(_char) == true))
        {
            return false;
        }
        return true;
    }
    private void SaveWord(string word)
    {
        if (String.IsNullOrEmpty(word) == false)
        {
            outputList.Add(new SentenceSplitResult()
            {
                isAWord = true,
                word = word
            });                
        }
    }
    private void SaveANotWord(char _char)
    {
        outputList.Add(new SentenceSplitResult()
        {
            isAWord = false,
            word = _char.ToString()
        });
    }

您可以尝试使用regex删除未被字母包围的撇号(即单引号),然后使用Char静态方法剥离所有其他字符。通过首先调用regex,您可以保留缩写撇号(例如can't),但删除单引号,如'Oh

string myText = "'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.'";
Regex reg = new Regex("'b['"']'b");
myText = reg.Replace(myText, "");
string[] listOfWords = RemoveCharacters(myText);
public string[] RemoveCharacters(string input)
{
    StringBuilder sb = new StringBuilder();
    foreach (char c in input)
    {
        if (Char.IsLetter(c) || Char.IsWhiteSpace(c) || c == '''')
           sb.Append(c);
    }
    return sb.ToString().Split(' ');
}