Подтвердить что ты не робот

Как разделить текст на слова?

Как разбить текст на слова?

Пример текста:

"О, ты не можешь с этим поделать, - сказал Кот: - Мы все здесь сумасшедшие. Я псих. Ты злишься.

Слова в этой строке:

  • О
  • вы
  • не может
  • помощь
  • что
  • сказал
  • Cat
  • мы
  • все
  • безумен
  • здесь
  • Я
  • безумен
  • Вы
  • безумен
4b9b3361

Ответ 1

Разделите текст на пробелы, затем пунктирную обрезку.

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

Соответствует точно примеру.

Ответ 2

Сначала удалите все специальные символы:

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(' ');

Для более простого решения С# для удаления специальных символов (которое вы можете легко изменить), добавьте этот метод расширения (я добавил поддержку апострофа):

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(' ');

Вы будете удивлены, узнав, что этот метод расширения очень эффективен (несомненно, намного эффективнее, чем Regex), поэтому я предлагаю вам использовать его;)

Обновить

Я согласен, что это только английский подход, но чтобы сделать его совместимым с Юникодом, все что вам нужно сделать, это заменить:

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

С:

char.IsLetter(c)

Поддерживает Unicode,.Net также предлагает вам char.IsSymbol и char.IsLetterOrDigit для различных случаев

Ответ 3

Просто добавьте вариацию на @Adam Fridental ответ, который очень хорош, вы можете попробовать это Regex:

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

Ответ 4

Если вы не хотите использовать объект 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",

Ответ 5

Это одно из решений, я не использую какой-либо вспомогательный класс или метод.

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

Ответ 6

Вы можете попробовать использовать регулярное выражение для удаления апострофов, которые не окружены буквами (то есть одинарные кавычки), а затем с помощью статических методов Char для удаления всех других символов. Вызывая регулярное выражение, вы можете сохранить апострофы сжатия (например, 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(' ');
}

Ответ 7

Если вы хотите использовать "для цикла", чтобы проверить каждый символ и сохранить все знаки препинания во входной строке, я создал этот класс. Метод GetSplitSentence() возвращает список SentenceSplitResult. В этом списке сохранены все слова и все знаки препинания и цифры. Каждая сохраненная пунктуация или цифры - это элемент списка. ПредложениеSplitResult.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()
        });
    }