Làm cách nào để xóa tất cả các ký tự không chữ và số khỏi chuỗi trừ dấu gạch ngang?


606

Làm cách nào để xóa tất cả các ký tự không phải chữ và số khỏi một chuỗi trừ ký tự dấu gạch ngang và dấu cách?

Câu trả lời:


870

Thay thế [^a-zA-Z0-9 -]bằng một chuỗi trống.

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
str = rgx.Replace(str, "");

79
Đáng nói là -phải ở cuối lớp nhân vật, hoặc thoát bằng dấu gạch chéo ngược, để tránh bị sử dụng cho một phạm vi.
Peter Boughton

6
@Dan đặt cờ toàn cầu trong regex của bạn - không có điều đó, nó chỉ thay thế trận đấu đầu tiên. Google nhanh chóng sẽ cho bạn biết cách đặt cờ toàn cầu trong biểu thức chính quy cổ điển. Nếu không, hãy tìm một replaceAllchức năng thay vì replace.
Amarghosh

20
Đây là phiên bản regex được biên dịch: return Regex.Replace(str, "[^a-zA-Z0-9_.]+", "", RegexOptions.Compiled); Câu hỏi cơ bản tương tự
Paige Watson

13
@MGOwen bởi vì mỗi khi bạn sử dụng "", bạn đang tạo một đối tượng mới do các chuỗi không thay đổi. Khi bạn sử dụng string.empty, bạn đang sử dụng lại một thể hiện duy nhất cần thiết để thể hiện một chuỗi trống nhanh hơn cũng như hiệu quả hơn.
Brian Scott

17
@BrianScott Tôi biết cái này đã cũ, nhưng đã được tìm thấy trong một tìm kiếm nên tôi cảm thấy nó có liên quan. Điều này thực sự phụ thuộc vào phiên bản .NET mà bạn đang chạy. > 2.0 sử dụng ""& string.Emptyhoàn toàn giống nhau. stackoverflow.com/questions/151472/ Mạnh
Jared

348

Tôi có thể đã sử dụng RegEx, họ có thể cung cấp giải pháp tao nhã nhưng chúng có thể gây ra các vấn đề về hiệu suất. Đây là một giải pháp

char[] arr = str.ToCharArray();

arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c) 
                                  || char.IsWhiteSpace(c) 
                                  || c == '-')));
str = new string(arr);

Khi sử dụng khung nhỏ gọn (không có FindAll)

Thay thế FindAll bằng 1

char[] arr = str.Where(c => (char.IsLetterOrDigit(c) || 
                             char.IsWhiteSpace(c) || 
                             c == '-')).ToArray(); 

str = new string(arr);

1 Bình luận của ShawnFeatherly


41
trong thử nghiệm của tôi, kỹ thuật này nhanh hơn nhiều. nói chính xác, nó chỉ nhanh hơn 3 lần so với kỹ thuật Regex Thay thế.
Dan

12
Khung nhỏ gọn không có FindAll, bạn có thể thay thế FindAll bằngchar[] arr = str.Where(c => (char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-')).ToArray();
ShawnFeatherly

2
có ai đã thử cái này chưa? Điều đó đã không làm việc cả. - nhưng điều này đã làm cho tôi: chuỗi str2 = chuỗi mới (str.Where (c => (char.IsLetterOrDigit (c))). ToArray ());
KevinDeus

48

Bạn co thể thử:

string s1 = Regex.Replace(s, "[^A-Za-z0-9 -]", "");

Trong trường hợp slà chuỗi của bạn.


1
OP yêu cầu gạch ngang không gạch dưới
Sean B

39

Sử dụng System.Linq

string withOutSpecialCharacters = new string(stringWithSpecialCharacters.Where(c =>char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-').ToArray());

@Michael Nó tương tự nhưng ít nhất đây là một lớp lót, thay vì 3 dòng. Tôi muốn nói rằng đủ để làm cho nó một câu trả lời khác nhau.
Dymas

1
@Dymas Bây giờ tôi đồng ý rằng nó có thể chấp nhận được, nhưng không phải vì khoảng trắng khác nhau. Rõ ràng phần tương đương về chức năng (chỉ có tên var khác nhau) đã được chỉnh sửa sau khi câu trả lời này được viết.
Michael - Clay Shirky ở đâu

1
@ZainAli, nếu bạn thực hiện một chỉnh sửa tầm thường và ping tôi, tôi sẽ đảo ngược downvote của tôi. Tôi xin lỗi vì bất kỳ sự ám chỉ của đạo văn.
Michael - Clay Shirky ở đâu

22

Regex là [^\w\s\-]*:

\stốt hơn là sử dụng thay vì dấu cách ( ), vì có thể có một tab trong văn bản.


1
trừ khi bạn muốn loại bỏ các tab.
Matt Ellen

... Và các dòng mới, và tất cả các nhân vật khác được coi là "khoảng trắng".
Peter Boughton

6
Giải pháp này vượt trội hơn nhiều so với các giải pháp trên vì nó cũng hỗ trợ các ký tự quốc tế (không phải tiếng Anh). <! - ngôn ngữ: c # -> chuỗi s = "Mötley Crue: の 氏 và Kanji và Hiragana い"; chuỗi r = Regex.Replace (s, "[^ \\ w \\ s -] *", ""); Ở trên tạo ra r với: Mötley Crue の và Kanji và Hiragana あ
danglund

1
Sử dụng @ để thoát \ chuyển đổi trong chuỗi: @ "[^ \ w \ s -] *"
Jakub Pawlinski

1
nó, uhhh ... không loại bỏ dấu gạch dưới? được coi là một ký tự "từ" bằng cách thực hiện regex trong suốt quá trình tạo, nhưng nó không phải là chữ và số, dấu gạch ngang hoặc dấu cách ... (?)
Code

14

Dựa trên câu trả lời cho câu hỏi này, tôi đã tạo một lớp tĩnh và thêm chúng. Nghĩ rằng nó có thể hữu ích cho một số người.

public static class RegexConvert
{
    public static string ToAlphaNumericOnly(this string input)
    {
        Regex rgx = new Regex("[^a-zA-Z0-9]");
        return rgx.Replace(input, "");
    }

    public static string ToAlphaOnly(this string input)
    {
        Regex rgx = new Regex("[^a-zA-Z]");
        return rgx.Replace(input, "");
    }

    public static string ToNumericOnly(this string input)
    {
        Regex rgx = new Regex("[^0-9]");
        return rgx.Replace(input, "");
    }
}

Sau đó, các phương thức có thể được sử dụng như:

string example = "asdf1234!@#$";
string alphanumeric = example.ToAlphaNumericOnly();
string alpha = example.ToAlphaOnly();
string numeric = example.ToNumericOnly();

2
Đối với ví dụ mà bạn cung cấp, nó cũng sẽ hữu ích nếu bạn cung cấp kết quả của từng phương thức.
c-chavez

7

Muốn một cái gì đó nhanh chóng?

public static class StringExtensions 
{
    public static string ToAlphaNumeric(this string self, params char[] allowedCharacters)
    {
        return new string(Array.FindAll(self.ToCharArray(), c => char.IsLetterOrDigit(c) || allowedCharacters.Contains(c)));
    }
}

Điều này sẽ cho phép bạn chỉ định những ký tự bạn muốn cho phép là tốt.


5

Đây là một giải pháp nhanh chóng thân thiện với phân bổ heap không phải là regex mà tôi đang tìm kiếm.

Phiên bản không an toàn.

public static unsafe void ToAlphaNumeric(ref string input)
{
    fixed (char* p = input)
    {
        int offset = 0;
        for (int i = 0; i < input.Length; i++)
        {
            if (char.IsLetterOrDigit(p[i]))
            {
                p[offset] = input[i];
                offset++;
            }
        }
        ((int*)p)[-1] = offset; // Changes the length of the string
        p[offset] = '\0';
    }
}

Và đối với những người không muốn sử dụng không an toàn hoặc không tin tưởng vào độ dài chuỗi.

public static string ToAlphaNumeric(string input)
{
    int j = 0;
    char[] newCharArr = new char[input.Length];

    for (int i = 0; i < input.Length; i++)
    {
        if (char.IsLetterOrDigit(input[i]))
        {
            newCharArr[j] = input[i];
            j++;
        }
    }

    Array.Resize(ref newCharArr, j);

    return new string(newCharArr);
}

4

Tôi đã tạo ra một giải pháp khác, bằng cách loại bỏ Điều khiển ký tự , đó là vấn đề ban đầu của tôi.

Nó là tốt hơn so với việc đưa vào một danh sách tất cả các ký tự "đặc biệt nhưng tốt"

char[] arr = str.Where(c => !char.IsControl(c)).ToArray();    
str = new string(arr);

Nó đơn giản hơn, vì vậy tôi nghĩ nó tốt hơn!


2

Đây là một phương pháp mở rộng sử dụng câu trả lời @ata làm nguồn cảm hứng.

"hello-world123, 456".MakeAlphaNumeric(new char[]{'-'});// yields "hello-world123456"

hoặc nếu bạn yêu cầu thêm các ký tự khác ngoài dấu gạch nối ...

"hello-world123, 456!?".MakeAlphaNumeric(new char[]{'-','!'});// yields "hello-world123456!"


public static class StringExtensions
{   
    public static string MakeAlphaNumeric(this string input, params char[] exceptions)
    {
        var charArray = input.ToCharArray();
        var alphaNumeric = Array.FindAll<char>(charArray, (c => char.IsLetterOrDigit(c)|| exceptions?.Contains(c) == true));
        return new string(alphaNumeric);
    }
}

1

Tôi sử dụng một biến thể của một trong những câu trả lời ở đây. Tôi muốn thay thế khoảng trắng bằng "-" để SEO thân thiện và cũng tạo chữ thường. Cũng không tham khảo system.web từ lớp dịch vụ của tôi.

private string MakeUrlString(string input)
{
    var array = input.ToCharArray();

    array = Array.FindAll<char>(array, c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-');

    var newString = new string(array).Replace(" ", "-").ToLower();
    return newString;
}

0

Đây là một phiên bản rất ngắn gọn

myString = myString.replace(/[^A-Za-z0-9 -]/g, "");

-1

Có một cách dễ dàng hơn nhiều với Regex.

private string FixString(string str)
{
    return string.IsNullOrEmpty(str) ? str : Regex.Replace(str, "[\\D]", "");
}

1
chỉ thay thế các ký tự không phải là số
frostymarvelous
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.