2010-09-09 36 views
14

Tôi đã một chuỗi trông giống như "A = 1,23; B = 2,345; C = 3,567"Java: làm thế nào để phân tích đôi từ regex

Tôi chỉ quan tâm đến "C = 3,567"

gì tôi đã cho đến nay là:

 Matcher m = Pattern.compile("C=\\d+.\\d+").matcher("A=1.23;B=2.345;C=3.567"); 

    while(m.find()){ 
     double d = Double.parseDouble(m.group()); 
     System.out.println(d); 
    } 

vấn đề là nó cho thấy 3 như riêng biệt từ 567

đầu ra:

3,0

567,0

tôi đang tự hỏi làm thế nào tôi có thể bao gồm các chữ số thập phân do đó kết quả đầu ra "3,567"

EDIT: tôi cũng muốn để phù hợp với C nếu nó không có một dấu thập phân: nên tôi muốn chụp 3567 cũng như 3.567

vì C = cũng được tích hợp vào mẫu, làm thế nào tôi có thể tách nó ra trước khi phân tích cú pháp gấp đôi?

+2

Dấu chấm (".") Không phải là chữ số. –

Trả lời

29

Tôi có thể bị nhầm lẫn trong phần này, vì lý do tách biệt hai là vì group() sẽ chỉ khớp với các kết quả trùng khớp cuối cùng, bất cứ điều gì được khớp với mỗi cuộc gọi đến find(). Xin cảm ơn, Mark Byers.

Để chắc chắn, bạn có thể giải quyết điều này bằng cách đặt toàn bộ phần bạn muốn bên trong "nhóm chụp", được thực hiện bằng cách đặt nó vào dấu ngoặc đơn. Điều này làm cho nó để bạn có thể nhóm các phần phù hợp với nhau của biểu thức chính quy của bạn thành một chuỗi con. mô hình của bạn sau đó sẽ như thế nào:

Pattern.compile("C=(\\d+\\.\\d+)") 

Đối với phân tích 3567 hoặc 3,567, mô hình của bạn sẽ làC=(\\d+(\\.\\d+)?)với nhóm 1 đại diện cho toàn bộ số.Ngoài ra, hãy lưu ý rằng vì bạn đặc biệt muốn khớp với một khoảng thời gian, bạn muốn thoát khỏi ký tự . (dấu chấm) của bạn để nó không được hiểu là mã thông báo "bất kỳ ký tự". Tuy nhiên, đối với đầu vào này, không quan trọng

Sau đó, để nhận được 3.567, bạn sẽ gọi cho m. group(1) để lấy nhóm đầu tiên (tính từ 1) nhóm được chỉ định. Điều này có nghĩa là cuộc gọi Double.parseDouble của bạn về cơ bản sẽ trở thành Double.parseDouble("3.567")

Vì đã lấy C = trong mẫu của bạn, vì tôi không thành thạo với RegExp, tôi có thể khuyên bạn split chuỗi đầu vào của bạn trên bán dấu hai chấm và sau đó kiểm tra xem mỗi phân tách có chứa C hay không; sau đó bạn có thể áp dụng các mô hình (với các nhóm chụp) để có được 3.567 từ Matcher của bạn.

Sửa Đối với các tổng quát hơn (và nhiều khả năng hữu ích!) Các trường hợp trong bình luận gawi, xin vui lòng sử dụng sau đây (từ http://www.regular-expressions.info/floatingpoint.html)

Pattern.compile("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?") 

này đã hỗ trợ cho dấu tùy chọn, hoặc là số nguyên tùy chọn hoặc tùy chọn phần thập phân và số mũ dương/âm tùy chọn. Chèn các nhóm chụp nơi bạn muốn chọn từng phần riêng lẻ. Số mũ tổng thể nằm trong nhóm riêng của nó để làm cho nó, như một toàn thể, tùy chọn.

+1

LƯU Ý: Regexp không xử lý các phao sau đây: 10 10. .1 1.3e10 1.2e-12 1.41e + 12 – gawi

+0

@gawi Cảm ơn bạn :) Tôi đã cập nhật câu trả lời với cụm từ thông dụng cần thực hiện thủ thuật . Là 10. được coi là một phao hợp lệ, với dấu thập phân nhưng không có chữ số sau? – btlachance

+1

10. là một chữ phao hợp lệ trong Java (cũng ... 10.f là chính xác) – gawi

2

Để phù hợp với bất kỳ chuỗi các chữ số và dấu chấm, bạn có thể thay đổi các biểu thức chính quy như sau:

"(?<=C=)[.\\d]+" 

Nếu bạn muốn chắc chắn rằng chỉ có một dấu chấm duy nhất bạn có thể muốn thử một cái gì đó như thế này:

"(?<=C=)\\d+(?:\\.\\d+)?" 

Bạn cũng nên biết rằng mẫu này có thể khớp với 1.2 trong ABC=1.2.3;. Bạn nên xem xét nếu bạn cần cải thiện biểu thức chính quy để xử lý chính xác tình huống này.

4

Cụm từ thông dụng của bạn chỉ phù hợp với các ký tự số. Để cũng so khớp dấu thập phân, bạn sẽ cần:

Pattern.compile("\\d+\\.\\d+") 

. được thoát vì điều này khớp với bất kỳ ký tự nào khi không thoát.

Lưu ý: điều này sau đó sẽ chỉ khớp với số có dấu thập phân mà bạn có trong ví dụ của mình.

1

nếu bạn cần phải xác nhận số thập phân với dấu chấm, dấu phẩy, mặt tích cực và tiêu cực:

Object testObject = "-1.5"; 
boolean isDecimal = Pattern.matches("^[\\+\\-]{0,1}[0-9]+[\\.\\,][0-9]+$", (CharSequence) testObject); 

Chúc may mắn.

+1

Không phải là {1} tiềm ẩn? – Cutter

+1

@cutter vâng, tôi không nhớ tại sao tôi lại thêm {1} đó. Có lẽ để rõ ràng hơn hoặc bởi vì tôi đã quá noob với regex trong năm 2015 xD – august0490

+0

Câu trả lời duy nhất xử lý các số âm (và dương với số + hàng đầu) một cách chính xác. – Robert

Các vấn đề liên quan