Bagaimana cara menghapus semua karakter non alfanumerik dari string kecuali tanda hubung?

606

Bagaimana cara menghapus semua karakter non alfanumerik dari string kecuali karakter dasbor dan spasi?

Luke101
sumber

Jawaban:

870

Ganti [^a-zA-Z0-9 -]dengan string kosong.

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
str = rgx.Replace(str, "");
Amarghosh
sumber
79
Layak disebutkan bahwa -harus di akhir kelas karakter, atau melarikan diri dengan garis miring terbalik, untuk mencegah digunakan untuk rentang.
Peter Boughton
6
@Dan atur bendera global di regex Anda - tanpa itu, itu hanya menggantikan pertandingan pertama. Google cepat harus memberi tahu Anda cara mengatur bendera global di ASP klasik. Jika tidak, cari replaceAllfungsi alih-alih replace.
Amarghosh
20
Berikut ini adalah versi kompilasi regex: return Regex.Replace(str, "[^a-zA-Z0-9_.]+", "", RegexOptions.Compiled); Pertanyaan dasar yang sama
Paige Watson
13
@MGOwen karena setiap kali Anda menggunakan "" Anda membuat objek baru karena string tidak dapat diubah. Ketika Anda menggunakan string.empty Anda menggunakan kembali instance tunggal yang diperlukan untuk merepresentasikan string kosong yang lebih cepat dan juga lebih efisien.
Brian Scott
17
@BrianScott Saya tahu ini sudah tua, tetapi ditemukan dalam pencarian jadi saya merasa ini relevan. Ini sebenarnya tergantung pada versi. NET yang Anda jalankan. > 2.0 menggunakan ""& string.Emptypersis sama. stackoverflow.com/questions/151472/…
Jared
348

Saya bisa menggunakan RegEx, mereka dapat memberikan solusi yang elegan tetapi mereka dapat menyebabkan masalah performane. Inilah salah satu solusinya

char[] arr = str.ToCharArray();

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

Saat menggunakan kerangka kerja ringkas (yang tidak memiliki FindAll)

Ganti FindAll dengan 1

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

str = new string(arr);

1 Komentar oleh ShawnFeatherly

ata
sumber
41
dalam pengujian saya, teknik ini jauh lebih cepat. tepatnya, itu hanya di bawah 3 kali lebih cepat daripada teknik Regex Replace.
Dan
12
Kerangka kerja yang ringkas tidak memiliki FindAll, Anda dapat mengganti char[] arr = str.Where(c => (char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-')).ToArray();
FindAll
2
Adakah yang sudah menguji ini? Itu tidak berhasil sama sekali. --tapi ini berhasil bagi saya: string str2 = string baru (str.Where (c => (char.IsLetterOrDigit (c))). ToArray ());
KevinDeus
48

Anda dapat mencoba:

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

Dimana ssenar Anda.

josephj1989
sumber
1
OP meminta tanda hubung bukan garis bawah
Sean B
39

Menggunakan System.Linq

string withOutSpecialCharacters = new string(stringWithSpecialCharacters.Where(c =>char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-').ToArray());
Zain Ali
sumber
@Michael Mirip tapi setidaknya ini satu liner, bukan 3 baris. Saya akan mengatakan itu cukup untuk membuatnya menjadi jawaban yang berbeda.
Dymas
1
@ Dymas Saya sekarang setuju bahwa itu dapat diterima, tetapi bukan karena spasinya berbeda. Rupanya bagian yang secara fungsional setara (hanya nama var berbeda) diedit setelah jawaban ini ditulis.
Michael - Di mana Clay Shirky
1
@ ZainAli, jika Anda mengedit sepele dan mem-ping saya, saya akan membalikkan downvote saya. Saya minta maaf atas sindiran penjiplakan.
Michael - Di mana Clay Shirky
22

Regex adalah [^\w\s\-]*:

\slebih baik digunakan daripada spasi ( ), karena mungkin ada tab di teks.

Benar Lembut
sumber
1
kecuali jika Anda ingin menghapus tab.
Matt Ellen
... dan baris baru, dan semua karakter lain dianggap "spasi putih".
Peter Boughton
6
Solusi ini jauh lebih unggul daripada solusi di atas karena juga mendukung karakter internasional (non-Inggris). <! - bahasa: c # -> string s = "Mötley Crue 日本人: の 氏 名 dan Kanji 愛 dan Hiragana あ い"; string r = Regex.Replace (s, "[^ \\ w \\ s -] *", ""); Di atas menghasilkan r dengan: Mötley Crue 日本人 の 氏 名 dan Kanji 愛 dan Hiragana あ い
danglund
1
Gunakan @ untuk keluar \ konversi dalam string: @ "[^ \ w \ s -] *"
Jakub Pawlinski
1
itu, uhhh ... tidak menghapus garis bawah? yang dianggap sebagai karakter "kata" dengan implementasi regex di seluruh kreasi, tetapi itu bukan alfanumerik, tanda hubung, atau spasi ... (?)
Code Jockey
14

Berdasarkan jawaban untuk pertanyaan ini, saya membuat kelas statis dan menambahkan ini. Pikir itu mungkin bermanfaat bagi sebagian orang.

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

Maka metode tersebut dapat digunakan sebagai:

string example = "asdf1234!@#$";
string alphanumeric = example.ToAlphaNumericOnly();
string alpha = example.ToAlphaOnly();
string numeric = example.ToNumericOnly();
Ppp
sumber
2
Untuk contoh yang Anda berikan itu juga akan berguna jika Anda memberikan hasil dari masing-masing metode.
c-chavez
7

Ingin sesuatu dengan cepat?

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

Ini akan memungkinkan Anda untuk menentukan karakter mana yang ingin Anda izinkan juga.

Zachare Sylvestre
sumber
5

Berikut adalah solusi ramah alokasi cepat tumpukan non-regex yang adalah apa yang saya cari.

Edisi tidak aman.

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

Dan bagi mereka yang tidak ingin menggunakan tidak aman atau tidak percaya peretasan panjang tali.

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);
}
BjarkeCK
sumber
4

Saya telah membuat solusi yang berbeda, dengan menghilangkan karakter Kontrol , yang merupakan masalah awal saya.

Itu lebih baik daripada memasukkan semua karakter "istimewa tapi bagus" dalam daftar

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

lebih sederhana, jadi saya pikir ini lebih baik!

Pinello
sumber
2

Berikut adalah metode ekstensi menggunakan jawaban @ata sebagai inspirasi.

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

atau jika Anda memerlukan karakter tambahan selain tanda hubung ...

"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);
    }
}
Aaron Hudon
sumber
1

Saya menggunakan variasi dari salah satu jawaban di sini. Saya ingin mengganti spasi dengan "-" sehingga SEO friendly dan juga membuat huruf kecil. Juga tidak mereferensikan system.web dari lapisan layanan saya.

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;
}
Philip Johnson
sumber
0

Ini adalah versi yang sangat singkat

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

Ada cara yang jauh lebih mudah dengan Regex.

private string FixString(string str)
{
    return string.IsNullOrEmpty(str) ? str : Regex.Replace(str, "[\\D]", "");
}
Pengembangan Syv
sumber
1
hanya menggantikan karakter non numerik
frostymarvelous