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

Как я могу удалить пунктуацию из строки?

Для части ответа на вопрос "надеюсь, что у вас есть ответ на 30 секунд" я специально ищу С#

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

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

Связано: Пунктуация полосы в Python

4b9b3361

Ответ 1

new string(myCharCollection.Where(c => !char.IsPunctuation(c)).ToArray());

Ответ 2

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

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 обычно медленнее, чем простые операции char. И эти операции LINQ кажутся мне излишними. И вы не можете использовать такой код в .NET 2.0...

Ответ 3

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

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

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

Изменить: версия Unicode-Aware будет следующей:

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

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

Ответ 4

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

 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, который лучше всего выполнял опубликованный пучок.

Ответ 5

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

 replace(YourString, RegularExpressionWithPunctuationMarks, Empty String)

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

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

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

(\p{P})

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

Ответ 6

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

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

Это LINQ sans WTF.

Ответ 7

Основываясь на идее GWLlosa, я смог придумать в высшей степени уродливый, но работающий:

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

Ответ 8

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

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

Ответ 9

Здесь немного другой подход с использованием linq. Мне нравится AviewAnew, но это позволяет избежать агрегации

        string myStr = "Hello there..';,]';';., Get rid of Punction";

        var s = from ch in myStr
                where !Char.IsPunctuation(ch)
                select ch;

        var bytes = UnicodeEncoding.ASCII.GetBytes(s.ToArray());
        var stringResult = UnicodeEncoding.ASCII.GetString(bytes);

Ответ 10

$newstr=ereg_replace("[[:punct:]]",'',$oldstr);

Ответ 11

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

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

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

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

Я пошел на обычную реализацию dotnetperls.

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

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

Cheers, Эндрю

Ответ 12

Если вы хотите использовать это для токенизирующего текста, вы можете использовать:

new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray())

Ответ 13

#include<string>
    #include<cctype>
    using namespace std;

    int main(int a, char* b[]){
    string strOne = "H,e.l/l!o W#[email protected]^l&d!!!";
    int punct_count = 0;

cout<<"before : "<<strOne<<endl;
for(string::size_type ix = 0 ;ix < strOne.size();++ix)   
{   
    if(ispunct(strOne[ix])) 
    {
            ++punct_count;  
            strOne.erase(ix,1); 
            ix--;
    }//if
}
    cout<<"after : "<<strOne<<endl;
                  return 0;
    }//main

Ответ 14

Для длинных строк я использую это:

var normalized = input
                .Where(c => !char.IsPunctuation(c))
                .Aggregate(new StringBuilder(),
                           (current, next) => current.Append(next), sb => sb.ToString());

работает намного лучше, чем использование конкатенаций строк (хотя я согласен с тем, что он менее интуитивно понятен).