Regex để xóa tất cả (không phải số HOẶC dấu chấm)


94

Tôi cần lọc văn bản như "joe ($ 3,004.50)" xuống còn 3004.50 nhưng regex rất tệ và không thể tìm thấy giải pháp phù hợp. Vì vậy, chỉ số và khoảng thời gian nên ở lại - mọi thứ khác được lọc. Tôi sử dụng C # và VS.net 2008 framework 3.5

Câu trả lời:


168

Điều này nên làm điều đó:

string s = "joe ($3,004.50)";
s = Regex.Replace(s, "[^0-9.]", "");

1
Về joe.smith ($3,004.50)thì sao? Đơn giản chỉ cần loại bỏ các lớp nhân vật vi phạm có thể khá sai.
Matthew Gunn

2
Tôi thực hiện một điều chỉnh nhỏ: Regex.Replace(s, "[^$0-9.]", "");Bạn muốn để lại ký hiệu đô la.
bodacydo

36

Regex là:

[^0-9.]

Bạn có thể cache regex:

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

sau đó sử dụng:

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

Tuy nhiên, bạn nên nhớ rằng một số nền văn hóa có các quy ước khác nhau để viết số tiền, chẳng hạn như: 3,004,50.


ATM quá lười biếng để xác minh, nhưng bạn không cần phải thoát. ?
Andrew Anderson

9
@Andrew: không, bên trong một lớp ký tự, .không có ý nghĩa đặc biệt.
Bart Kiers

2

Đối với câu trả lời được chấp nhận, MatthewGunn nêu ra một điểm hợp lệ là tất cả các chữ số, dấu phẩy và dấu chấm trong toàn bộ chuỗi sẽ được cô đọng lại với nhau. Điều này sẽ tránh được điều đó:

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

Có vẻ như trên regex có thêm dấu ngoặc đơn. Việc sử dụng (?:^|[^w.,])(\d[\d,.]+)(?=\W|$)cũng sẽ khớp với "h25" trong chuỗi "joe.smith25 ($ 3,004.50)"
Rivka

1

Cách tiếp cận loại bỏ các ký tự vi phạm có thể có vấn đề. Điều gì sẽ xảy ra nếu có một .chuỗi khác trong chuỗi ở đâu đó? Nó sẽ không bị xóa, mặc dù nó nên!

Loại bỏ các ký tự không hoặc dấu joe.smith ($3,004.50)chấm , chuỗi sẽ chuyển thành chuỗi không thể phân tích .3004.50.

Imho, tốt hơn là nên khớp một mẫu cụ thể và trích xuất nó bằng cách sử dụng một nhóm. Một cái gì đó đơn giản sẽ là tìm tất cả các dấu phẩy, chữ số và dấu chấm liền kề với regexp:

[\d,\.]+

Chạy thử nghiệm mẫu:

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"

Sau đó, đối với mỗi kết quả phù hợp, hãy xóa tất cả các dấu phẩy và gửi đến trình phân tích cú pháp. Để xử lý trường hợp tương tự 12.323.344, bạn có thể thực hiện một kiểm tra khác để xem rằng một chuỗi con phù hợp có nhiều nhất một ..


Regex này phù hợp với mọi thứ.
mindriot

Bây giờ nó phù hợp với mọi thứ ngoại trừ "".
mindriot

1
Khái niệm bạn đang đề xuất sẽ yêu cầu một regex phức tạp, khó đọc và gỡ lỗi. Có thể tốt hơn nếu chia nhỏ nó thành các bước với một số regex và điều kiện. Tôi có thể cung cấp câu trả lời (mặc dù được viết bằng Ruby vì tôi không biết c #.
mindriot

@mindriot Đã lấy điểm. Tôi đã thay đổi nó thành một cái gì đó minh bạch hơn.
Matthew Gunn

Bằng cách gửi đến trình phân tích cú pháp, bạn có nghĩa là một trong hai Single.Parse()hoặc Single.TryParse?
mindriot

1

Bạn đang xử lý một chuỗi - chuỗi là một IEumerable<char>, vì vậy bạn có thể sử dụng LINQ:

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

Console.WriteLine(result);   // 3004.50
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.