2009-01-07 28 views
55

Đối với phần hy vọng-to-có-một-câu trả lời-trong-30 giây của câu hỏi này, tôi đặc biệt đang tìm kiếm C#Làm cách nào tôi có thể tách dấu chấm câu khỏi chuỗi?

Nhưng trong trường hợp chung, cách tốt nhất để loại bỏ dấu câu trong bất kỳ trường hợp nào ngôn ngữ?

Tôi nên thêm: Lý tưởng nhất, các giải pháp sẽ không yêu cầu bạn liệt kê tất cả các dấu câu có thể có.

liên quan: Strip Punctuation in Python

+0

Các ngôn ngữ khác nhau, trên thực tế, khác nhau và tôi không nghĩ câu trả lời cho câu hỏi bạn đang yêu cầu. Bạn có thể hỏi về các ngôn ngữ cụ thể, hoặc ngôn ngữ nào là tốt nhất cho loại thao tác đó. –

Trả lời

3

Cách đơn giản nhất để làm braindead nó sẽ được sử dụng String.Replace

Một cách khác tôi sẽ tưởng tượng là một Regex.Replace và có biểu hiện thường xuyên của bạn với tất cả các dấu thích hợp đánh dấu trong đó.

13

Giả sử "tốt nhất" có nghĩa là "đơn giản" Tôi đề nghị sử dụng một cái gì đó như thế này:

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

Ví dụ này là dành cho Java, nhưng tất cả động cơ Regex đủ hiện đại nên hỗ trợ này (hoặc một cái gì đó tương tự).

Chỉnh sửa: phiên bản Unicode-Aware sẽ là:

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

Phiên bản đầu tiên chỉ nhìn vào ký tự dấu chứa trong ASCII.

+0

C# không có lớp 'Punct' nhưng nó có' P' – JProgrammer

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

Yup. Nó cung cấp năng lượng cho hoạt động chuỗi mà tôi đã đăng bên dưới. –

+4

LinQ không bao giờ ngừng làm tôi ngạc nhiên. – Dermot

+0

Rực rỡ. Càng đơn giản càng đẹp. –

8

Bạn có thể sử dụng phương pháp Regex.Replace:

replace(YourString, RegularExpressionWithPunctuationMarks, Empty String) 

Vì đây trả về một chuỗi, phương pháp của bạn sẽ trông giống như thế này:

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

Bạn có thể thay thế "[? !] "với thứ gì đó được thêm vào thứ hai nếu bạn muốn:

(\p{P}) 

Điều này sẽ tìm thấy bất kỳ dấu chấm câu nào.

+0

+1 cho việc sử dụng một lớp nhân vật unicode. Ngắn gọn, chính xác và tốt đẹp. –

4

Dựa tắt ý tưởng GWLlosa, tôi đã có thể đưa ra các vô cùng xấu xí, nhưng làm việc:

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

Tôi biết; đúng? Tôi sở thích của tôi là cam kết tội lỗi chống lại mã trong LINQ. Nhưng xin vui lòng, bằng mọi cách, làm cho nó tốt hơn. –

+4

Vui lòng tìm kiếm trợ giúp về tâm thần. –

+0

Đó là bậc hai chiều dài s; nếu bạn tăng gấp đôi chiều dài, mã sẽ chậm hơn bốn lần, vì toán tử + cho chuỗi phải tạo bản sao của chuỗi:/ –

1

Dưới đây là một cách tiếp cận hơi khác nhau sử dụng LINQ. Tôi thích AviewAnew nhưng điều này tránh được tổng hợp

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

Tại sao «IEnumerable ' thành mảng thành byte thành chuỗi chuyển đổi, tại sao không chỉ 'mới Chuỗi (s.ToArray()) '? Hoặc là những gì chuỗi mới sẽ làm theo mui xe nào? –

17

Tại sao không chỉ đơn giản là:

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

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

s = sb.ToString(); 

Việc sử dụng RegEx thường chậm hơn so với thao tác đơn giản char. Và những hoạt động LINQ đó trông giống như quá mức đối với tôi. Và bạn không thể sử dụng mã như vậy trong .NET 2.0 ...

+0

Lưu ý rằng cách tiếp cận này cũng cho phép bạn thay thế dấu chấm câu bằng khoảng trắng (ví dụ). Hữu ích cho tokenizing. –

0
#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 
9

Mô tả ý định, dễ dàng nhất để đọc (IMHO) và thực hiện tốt nhất:

s = s.StripPunctuation(); 

để thực hiện:

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

này được sử dụng thuật toán Hades32 của đó là thực hiện tốt nhất của bó đã đăng.

+0

miếng ngon thú vị: sau đây không phải là dấu chấm câu: $^+ | <> = –

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

Chủ đề này quá cũ, nhưng tôi không được phép đăng một giải pháp thanh lịch hơn (IMO).

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

Đó là LINQ sans WTF.

0

Đối với chuỗi dài tôi sử dụng này:

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

thực hiện tốt hơn nhiều so với sử dụng concatenations chuỗi (mặc dù tôi đồng ý đó là ít trực quan).

1

Tôi phải đối mặt với cùng một vấn đề và quan tâm đến tác động hiệu suất của việc gọi dấu câu cho mỗi lần kiểm tra.

Tôi tìm thấy bài đăng này: http://www.dotnetperls.com/char-ispunctuation.

Qua các dòng: char.IsPunctuation cũng xử lý Unicode trên đầu trang của ASCII. Phương thức khớp với một loạt ký tự bao gồm các ký tự điều khiển. Bởi definiton, phương pháp này là nặng và đắt tiền.

Điểm mấu chốt là cuối cùng tôi đã không đi vì nó ảnh hưởng đến hiệu suất của nó trên quy trình ETL của tôi.

Tôi đã thực hiện tùy chỉnh hiển thị các dấu chấm.

Và nhô FYI, đây là một số mã rút ra từ những câu trả lời trước để có được danh sách của tất cả các ký tự dấu (trừ những người điều khiển):

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

Chúc mừng, Andrew

1

Nếu bạn muốn để sử dụng thông tin này để mã hóa văn bản, bạn có thể sử dụng:

new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray()) 
Các vấn đề liên quan