Regex untuk menghapus semua (non numerik ATAU titik)

97

Saya membutuhkan teks seperti "joe ($ 3.004.50)" untuk disaring ke 3004,50 tetapi saya buruk di regex dan tidak dapat menemukan solusi yang sesuai. Jadi hanya angka dan titik yang harus tetap ada - yang lainnya difilter. Saya menggunakan C # dan VS.net 2008 framework 3.5

Siap Cent
sumber

Jawaban:

172

Ini harus melakukannya:

string s = "joe ($3,004.50)";
s = Regex.Replace(s, "[^0-9.]", "");
josephj1989
sumber
2
Tentang apa joe.smith ($3,004.50)? Hanya menghapus kelas karakter yang menyinggung bisa menjadi sangat salah.
Matthew Gunn
2
Saya membuat satu koreksi kecil: Regex.Replace(s, "[^$0-9.]", "");Anda ingin meninggalkan tanda dolar.
bodacydo
37

Regexnya adalah:

[^0-9.]

Anda dapat meng-cache regex:

Regex not_num_period = new Regex("[^0-9.]")

lalu gunakan:

string result = not_num_period.Replace("joe ($3,004.50)", "");

Namun, Anda harus ingat bahwa beberapa budaya memiliki konvensi yang berbeda untuk menulis jumlah uang, seperti: 3.004,50.

Matthew Flaschen
sumber
ATM terlalu malas untuk memverifikasi, tetapi Anda tidak perlu keluar dari. ?
Andrew Anderson
9
@ Andrew: tidak, di dalam kelas karakter, .tidak ada arti khusus.
Bart Kiers
3

Anda berurusan dengan string - string adalah an IEumerable<char>, jadi Anda dapat menggunakan LINQ:

var input = "joe ($3,004.50)";
var result = String.Join("", input.Where(c => Char.IsDigit(c) || c == '.'));

Console.WriteLine(result);   // 3004.50
wb
sumber
2

Untuk jawaban yang diterima, MatthewGunn memunculkan poin yang valid bahwa semua digit, koma, dan titik di seluruh string akan diringkas bersama. Ini akan menghindari hal itu:

string s = "joe.smith ($3,004.50)";
Regex r = new Regex(@"(?:^|[^w.,])(\d[\d,.]+)(?=\W|$)/)");
Match m = r.match(s);
string v = null;
if (m.Success) {
  v = m.Groups[1].Value;
  v = Regex.Replace(v, ",", "");
}
mindriot
sumber
Sepertinya regex di atas memiliki tanda kurung ekstra. Penggunaan (?:^|[^w.,])(\d[\d,.]+)(?=\W|$)juga akan cocok dengan "h25" dalam string "joe.smith25 ($ 3.004,50)"
Rivka
1

Pendekatan menghapus karakter yang menyinggung berpotensi menimbulkan masalah. Bagaimana jika ada .string lain di suatu tempat? Itu tidak akan dihapus, meskipun seharusnya!

Menghapus non-digit atau titik, string joe.smith ($3,004.50)akan berubah menjadi tidak dapat diuraikan .3004.50.

Imho, lebih baik mencocokkan pola tertentu, dan mengekstraknya menggunakan grup. Sesuatu yang sederhana adalah menemukan semua koma, angka, dan titik yang berdekatan dengan regexp:

[\d,\.]+

Contoh uji coba:

Pattern understood as:
[\d,\.]+
Enter string to check if matches pattern
>  a2.3 fjdfadfj34  34j3424  2,300 adsfa    
Group 0 match: "2.3"
Group 0 match: "34"
Group 0 match: "34"
Group 0 match: "3424"
Group 0 match: "2,300"

Kemudian untuk setiap pertandingan, hapus semua koma dan kirimkan ke parser. Untuk menangani kasus seperti ini 12.323.344, Anda dapat melakukan pemeriksaan lagi untuk melihat bahwa substring yang cocok memiliki paling banyak satu ..

Matthew Gunn
sumber
Regex ini cocok dengan semuanya.
mindriot
Sekarang cocok dengan semuanya kecuali "".
mindriot
1
Konsep yang Anda usulkan akan membutuhkan regex kompleks yang sulit dibaca dan di-debug. Mungkin lebih baik untuk memecahnya menjadi beberapa langkah dengan beberapa ekspresi reguler dan kondisional. Saya dapat memberikan jawaban (meskipun ditulis dalam Ruby karena saya tidak tahu c #.
mindriot
@mindriot Poin sudah diambil. Saya mengubahnya menjadi sesuatu yang lebih transparan.
Matthew Gunn
Dengan send to parser, maksud Anda salah satu Single.Parse()atau Single.TryParse?
mindriot