Как я могу снять пунктуацию со строки? - PullRequest
63 голосов
/ 07 января 2009

В этой части вопроса "я надеюсь получить ответ в течение 30 секунд" я специально ищу C #

Но в общем случае, как лучше убрать пунктуацию на любом языке?

Я должен добавить: В идеале решения не требуют перечисления всех возможных знаков препинания.

Похожие: Пунктуация в Python

Ответы [ 14 ]

99 голосов
/ 07 января 2009
new string(myCharCollection.Where(c => !char.IsPunctuation(c)).ToArray());
18 голосов
/ 07 января 2009

Почему бы просто:

string s = "sxrdct?fvzguh,bij.";
var sb = new StringBuilder();

foreach (char c in s)
{
   if (!char.IsPunctuation(c))
      sb.Append(c);
}

s = sb.ToString();

Использование RegEx обычно медленнее, чем простые операции с символами. И эти операции LINQ кажутся мне излишними. И вы не можете использовать такой код в .NET 2.0 ...

13 голосов
/ 07 января 2009

Предполагая, что «лучший» означает «самый простой», я предлагаю использовать что-то вроде этого:

String stripped = input.replaceAll("\\p{Punct}+", "");

Этот пример предназначен для Java, , но все достаточно современные движки Regex должны поддерживать это (или что-то подобное).

Редактировать: Unicode-Aware версия будет выглядеть так:

String stripped = input.replaceAll("\\p{P}+", "");

В первой версии рассматриваются только знаки препинания, содержащиеся в ASCII.

11 голосов
/ 17 июня 2010

Описывает намерение, легче читать (ИМХО) и лучше всего работает:

 s = s.StripPunctuation();

реализовать:

public static class StringExtension
{
    public static string StripPunctuation(this string s)
    {
        var sb = new StringBuilder();
        foreach (char c in s)
        {
            if (!char.IsPunctuation(c))
                sb.Append(c);
        }
        return sb.ToString();
    }
}

Это использует алгоритм Hades32, который был лучшим из всех опубликованных.

8 голосов
/ 07 января 2009

Вы можете использовать метод regex.replace:

 replace(YourString, RegularExpressionWithPunctuationMarks, Empty String)

Так как это возвращает строку, ваш метод будет выглядеть примерно так:

 string s = Regex.Replace("Hello!?!?!?!", "[?!]", "");

Вы можете заменить «[?!]» На что-то более сложное, если хотите:

(\p{P})

Это должно найти любую пунктуацию.

6 голосов
/ 29 сентября 2011

Эта ветка настолько старая, но я бы не стал публиковать более элегантное (IMO) решение.

string inputSansPunc = input.Where(c => !char.IsPunctuation(c)).Aggregate("", (current, c) => current + c);

Это LINQ без WTF.

4 голосов
/ 07 января 2009

Исходя из идеи Г.В.Ллосы, я смог придумать в высшей степени безобразный, но работающий:

string s = "cat!";
s = s.ToCharArray().ToList<char>()
      .Where<char>(x => !char.IsPunctuation(x))
      .Aggregate<char, string>(string.Empty, new Func<string, char, string>(
             delegate(string s, char c) { return s + c; }));
3 голосов
/ 07 января 2009

Самый простой способ сделать это - использовать string.replace

Другой способ, которым я мог бы представить, это regex.replace и ваше регулярное выражение со всеми соответствующими знаками препинания.

2 голосов
/ 05 апреля 2016

Если вы хотите использовать это для токенизации текста, вы можете использовать:

new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray())
1 голос
/ 19 апреля 2015

Я столкнулся с той же проблемой и был обеспокоен влиянием на производительность вызова IsPunctuation для каждой отдельной проверки.

Я нашел это сообщение: http://www.dotnetperls.com/char-ispunctuation.

Через строки: char.IsPunctuation также обрабатывает Unicode поверх ASCII. Метод сопоставляет группу символов, включая управляющие символы. По определению, этот метод тяжелый и дорогой.

Суть в том, что я, наконец, не пошел на это из-за влияния производительности на мой процесс ETL.

Я пошел за пользовательскую реализацию dotnetperls.

И только что, к вашему сведению, вот код, полученный из предыдущих ответов для получения списка всех знаков препинания (кроме контрольных):

var punctuationCharacters = new List<char>();

        for (int i = char.MinValue; i <= char.MaxValue; i++)
        {
            var character = Convert.ToChar(i);

            if (char.IsPunctuation(character) && !char.IsControl(character))
            {
                punctuationCharacters.Add(character);
            }
        }

        var commaSeparatedValueOfPunctuationCharacters = string.Join("", punctuationCharacters);

        Console.WriteLine(commaSeparatedValueOfPunctuationCharacters);

Ура, Andrew

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...