Regex เพื่อลบทั้งหมด (ไม่ใช่ตัวเลขหรือจุด)


97

ฉันต้องการให้ข้อความเช่น "joe ($ 3,004.50)" ถูกกรองลงเหลือ 3004.50 แต่ regex แย่มากและไม่สามารถหาวิธีแก้ปัญหาที่เหมาะสมได้ ดังนั้นควรมีเพียงตัวเลขและจุดเท่านั้น - ทุกอย่างจะถูกกรอง ฉันใช้ C # และ VS.net 2008 framework 3.5

คำตอบ:


172

สิ่งนี้ควรทำ:

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

2
เกี่ยวกับอะไรjoe.smith ($3,004.50)? การลบคลาสตัวละครที่ไม่เหมาะสมก็อาจผิดพลาดได้
Matthew Gunn

2
ฉันทำการแก้ไขเล็ก ๆ น้อย ๆ : Regex.Replace(s, "[^$0-9.]", "");คุณต้องการทิ้งเครื่องหมายดอลลาร์
bodacydo

37

regex คือ:

[^0-9.]

คุณสามารถแคช regex:

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

จากนั้นใช้:

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

อย่างไรก็ตามคุณควรจำไว้ว่าบางวัฒนธรรมมีระเบียบการเขียนจำนวนเงินที่แตกต่างกันเช่น 3.004,50


ATM ขี้เกียจเกินไปในการตรวจสอบ แต่คุณไม่จำเป็นต้องหนีไฟล์. เหรอ?
Andrew Anderson

9
@ แอนดรูว์: ไม่ภายในคลาสตัวละคร.ไม่มีความหมายพิเศษ
Bart Kiers

3

คุณกำลังจัดการกับสตริง - สตริงคือ an IEumerable<char>ดังนั้นคุณสามารถใช้ LINQ:

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

Console.WriteLine(result);   // 3004.50

2

สำหรับคำตอบที่ได้รับการยอมรับ MatthewGunn จะยกจุดที่ถูกต้องว่าตัวเลขเครื่องหมายจุลภาคและจุดทั้งหมดในสตริงทั้งหมดจะรวมเข้าด้วยกัน สิ่งนี้จะหลีกเลี่ยงสิ่งนั้น:

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

ดูเหมือนว่า regex ด้านบนจะมีวงเล็บพิเศษ การใช้(?:^|[^w.,])(\d[\d,.]+)(?=\W|$)จะจับคู่ "h25" ในสตริง "joe.smith25 ($ 3,004.50)" ด้วย
Rivka

1

วิธีการลบตัวละครที่ไม่เหมาะสมอาจเป็นปัญหาได้ จะเกิดอะไรขึ้นถ้ามีสายอื่น.อยู่ในสตริง? มันจะไม่ถูกลบออกแม้ว่ามันควรจะเป็น!

การลบตัวเลขที่ไม่ใช่ตัวเลขหรือจุดออกสตริงjoe.smith ($3,004.50)จะเปลี่ยนเป็นส่วนที่ไม่สามารถวิเคราะห์.3004.50ได้

Imho ควรจับคู่รูปแบบเฉพาะและแยกออกโดยใช้กลุ่ม สิ่งง่ายๆคือการค้นหาเครื่องหมายจุลภาคตัวเลขและจุดที่ต่อเนื่องกันทั้งหมดด้วย regexp:

[\d,\.]+

ตัวอย่างการทดสอบ:

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"

จากนั้นสำหรับการแข่งขันแต่ละรายการให้ลบเครื่องหมายจุลภาคทั้งหมดและส่งไปยังโปรแกรมแยกวิเคราะห์ หากต้องการจัดการกรณีเช่น12.323.344คุณสามารถตรวจสอบอีกครั้งเพื่อดูว่าสตริงย่อยที่ตรงกันมีมากที่สุดหนึ่ง.รายการ


regex นี้ตรงกับทุกอย่าง
mindriot

""ตอนนี้มันตรงกับทุกอย่างยกเว้น
mindriot

1
แนวคิดที่คุณเสนอจะต้องใช้นิพจน์ทั่วไปที่ซับซ้อนซึ่งยากต่อการอ่านและแก้ไขข้อบกพร่อง อาจจะดีกว่าถ้าแยกย่อยออกเป็นขั้นตอนด้วย regex และ conditionals หลาย ๆ อย่าง ฉันสามารถให้คำตอบได้ (แม้ว่าจะเขียนด้วย Ruby เพราะฉันไม่รู้ c #
mindriot

@mindriot Point ถ่าย. ฉันเปลี่ยนเป็นสิ่งที่โปร่งใสมากขึ้น
Matthew Gunn

โดยส่งไปยัง parser คุณหมายถึงอย่างใดอย่างหนึ่งSingle.Parse()หรือSingle.TryParse?
mindriot
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.