ฉันจะลบอักขระที่ไม่ใช่ตัวอักษรและตัวเลขทั้งหมดออกจากสตริงยกเว้นเส้นประได้อย่างไร


606

ฉันจะลบอักขระที่ไม่ใช่ตัวอักษรและตัวเลขทั้งหมดออกจากสตริงยกเว้นอักขระเส้นประและอักขระเว้นวรรคได้อย่างไร

คำตอบ:


870

แทนที่[^a-zA-Z0-9 -]ด้วยสตริงว่าง

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

79
เป็นมูลค่าการกล่าวขวัญว่า-จะต้องอยู่ที่ส่วนท้ายของตัวละครคลาสหรือหลบหนีด้วยแบ็กสแลชเพื่อป้องกันการใช้ช่วง
Peter Boughton

6
@Dan ตั้งค่าสถานะโกลบอลใน regex ของคุณ - หากไม่มีมันก็แค่แทนที่การแข่งขันครั้งแรก google ฉบับย่อควรบอกวิธีตั้งค่าสถานะโกลบอลใน regex ASP แบบคลาสสิก มิฉะนั้นมองหาฟังก์ชั่นแทนreplaceAll replace
Amarghosh

20
ต่อไปนี้เป็นรุ่นที่รวบรวม Regex: return Regex.Replace(str, "[^a-zA-Z0-9_.]+", "", RegexOptions.Compiled); คำถามพื้นฐานเดียวกัน
Paige Watson

13
@MGOwen เพราะทุกครั้งที่คุณใช้ "" คุณกำลังสร้างวัตถุใหม่เนื่องจากสตริงไม่เปลี่ยนรูป เมื่อคุณใช้ string.empty คุณจะใช้อินสแตนซ์เดียวที่จำเป็นสำหรับการแทนค่าสตริงว่างที่กลับมาใช้ใหม่ซึ่งเร็วกว่าและมีประสิทธิภาพมากกว่า
Brian Scott

17
@BrianScott ฉันรู้ว่านี่เก่า แต่ถูกค้นพบในการค้นหาดังนั้นฉันรู้สึกว่ามันมีความเกี่ยวข้อง ขึ้นอยู่กับเวอร์ชันของ. NET ที่คุณใช้ > 2.0 ใช้""และstring.Emptyเหมือนกันทุกประการ stackoverflow.com/questions/151472/…
Jared

348

ฉันสามารถใช้ RegEx พวกเขาสามารถให้บริการโซลูชันที่หรูหรา แต่อาจทำให้เกิดปัญหาเกี่ยวกับ performane นี่คือทางออกหนึ่ง

char[] arr = str.ToCharArray();

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

เมื่อใช้เฟรมเวิร์กขนาดกะทัดรัด (ซึ่งไม่มี FindAll)

แทนที่ FindAll ด้วย1

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

str = new string(arr);

1 ความคิดเห็นโดย ShawnFeatherly


41
ในการทดสอบของฉันเทคนิคนี้เร็วขึ้นมาก เพื่อความแม่นยำมันเร็วกว่าเทคนิคการแทนที่ Regex เพียง 3 เท่า
ด่าน

12
เฟรมเวิร์กขนาดกะทัดรัดไม่มี FindAll คุณสามารถแทนที่ FindAll ด้วยchar[] arr = str.Where(c => (char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-')).ToArray();
ShawnFeatherly

2
มีใครทดสอบหรือไม่ นั่นไม่ได้ผลเลย - แต่สิ่งนี้ทำเพื่อฉัน: string str2 = สตริงใหม่ (str.Where (c => (char.IsLetterOrDigit (c))). ToArray ());
KevinDeus

48

คุณสามารถลอง:

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

sสตริงของคุณอยู่ที่ไหน


1
OP ขอขีดล่างไม่ใช่ขีด
ฌอน B

39

ใช้ System.Linq

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

@Michael มันคล้ายกัน แต่อย่างน้อยนี่คือหนึ่งซับมากกว่า 3 บรรทัด ฉันจะบอกว่าเพียงพอที่จะทำให้มันเป็นคำตอบที่แตกต่างกัน
Dymas

1
@Dymas ฉันเห็นด้วยว่ามันเป็นที่ยอมรับ แต่ไม่ใช่เพราะพื้นที่ว่างนั้นแตกต่างกัน เห็นได้ชัดว่ามีการแก้ไขส่วนที่เทียบเท่ากับหน้าที่ (เฉพาะชื่อ var แตกต่างกัน) หลังจากเขียนคำตอบนี้แล้ว
Michael - ที่ไหน Shirky Clay อยู่

1
@ ZainAli ถ้าคุณทำการแก้ไขเล็กน้อยและ ping ฉันฉันจะย้อนกลับ downvote ของฉัน ฉันขออภัยในความไม่มั่นใจในการลอกเลียนแบบ
ไมเคิล - Clay Shirky อยู่ที่ไหน

22

regex คือ[^\w\s\-]*:

\sดีกว่าที่จะใช้แทน space ( ) เพราะอาจมีแท็บในข้อความ


1
ยกเว้นว่าคุณต้องการลบแท็บ
Matt Ellen

... และ newlines และตัวละครอื่น ๆ ทั้งหมดถือว่าเป็น "ช่องว่าง"
Peter Boughton

6
โซลูชันนี้เหนือกว่าโซลูชันด้านบนเนื่องจากรองรับอักขระนานาชาติ (ที่ไม่ใช่ภาษาอังกฤษ) <! - language: c # -> string s = "Mötley Crue 日本人: の氏名และคันจิ愛และฮิรางานะあい"; string r = Regex. แทนที่ (s, "[^ \\ w \\ s -] *", ""); รายการด้านบนผลิตโดย: Mötley Crue 日本人の氏名และ Kanji 愛และ Hiragana あい
danglund

1
ใช้ @ เพื่อยกเว้น \ การแปลงเป็นสตริง: @ "[^ \ w \ s -] *"
Jakub Pawlinski

1
มันเอ่อ ... ไม่ลบขีดล่างใช่ไหม ที่ถือว่าเป็นอักขระ "คำ" โดยการใช้ regex ข้ามการสร้าง แต่ไม่ใช่ตัวอักษรและตัวเลขขีดกลางหรือช่องว่าง ... (?)
รหัส Jockey

14

จากคำตอบสำหรับคำถามนี้ฉันได้สร้างคลาสแบบคงที่และเพิ่มสิ่งเหล่านี้ คิดว่าอาจมีประโยชน์สำหรับบางคน

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

จากนั้นวิธีการสามารถใช้เป็น:

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

2
สำหรับตัวอย่างที่คุณให้ไว้ก็จะมีประโยชน์เช่นกันหากคุณให้ผลลัพธ์ของแต่ละวิธี
c-chavez

7

ต้องการอะไรที่รวดเร็ว

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

การทำเช่นนี้จะช่วยให้คุณสามารถระบุอักขระที่คุณต้องการอนุญาตได้เช่นกัน


5

นี่คือโซลูชันการจัดสรรฮีปที่ไม่ใช่การ regex ที่เป็นมิตรซึ่งเป็นสิ่งที่ฉันกำลังมองหา

ฉบับที่ไม่ปลอดภัย

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

และสำหรับผู้ที่ไม่ต้องการใช้ที่ไม่ปลอดภัยหรือไม่เชื่อใจแฮ็คความยาวสายอักขระ

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

ฉันได้แก้ปัญหาที่แตกต่างออกไปโดยกำจัดตัวควบคุมซึ่งเป็นปัญหาดั้งเดิมของฉัน

มันดีกว่าใส่ไว้ในรายการตัวอักษร "พิเศษ แต่ดี" ทั้งหมด

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

มันง่ายกว่าดังนั้นฉันคิดว่ามันจะดีกว่า!


2

นี่คือวิธีการขยายโดยใช้คำตอบ@ataเป็นแรงบันดาลใจ

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

หรือถ้าคุณต้องการอักขระเพิ่มเติมนอกเหนือจากเครื่องหมายขีดคั่น ...

"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

ฉันใช้รูปแบบหนึ่งในคำตอบที่นี่ ฉันต้องการแทนที่ช่องว่างด้วย "-" เพื่อให้ SEO เป็นมิตรและทำตัวพิมพ์เล็ก ยังไม่อ้างอิง system.web จากชั้นบริการของฉัน

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


-1

มีวิธีที่ง่ายกว่ามากกับ Regex

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

1
แทนที่อักขระที่ไม่ใช่ตัวเลขเท่านั้น
frostymarvelous
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.