2009-08-03 36 views
15

Tôi đã chuỗi nàyJava - Extract chuỗi với Regex

String myString ="A~BC~FGH~~zuzy|XX~ 1234~ ~~ABC~01/01/2010 06:30~BCD~01/01/2011 07:45"; 

và tôi cần phải giải nén những 3 chuỗi con

06:30
07:45

Nếu tôi sử dụng regex này \ d {2} \: \\ d {2} tôi chỉ có thể trích xuất giờ đầu tiên 06:30

Pattern depArrHours = Pattern.compile("\\d{2}\\:\\d{2}"); 
Matcher matcher = depArrHours.matcher(myString); 
String firstHour = matcher.group(0); 
String secondHour = matcher.group(1); (IndexOutOfBoundException no Group 1) 

matcher.group (1) ném ngoại lệ.
Ngoài ra tôi không biết cách trích xuất 1234. Chuỗi này có thể thay đổi nhưng luôn xuất hiện sau 'XX ~'
Bạn có ý tưởng nào về cách đối sánh các chuỗi này với các biểu thức chính quy không?

CẬP NHẬT

Nhờ Adam gợi ý tôi đã tại regex này phù hợp với chuỗi của tôi

Pattern p = Pattern.compile(".*XX~ (\\d{3,4}).*(\\d{1,2}:\\d{2}).*(\\d{1,2}:\\d{2})"; 

tôi phù hợp với số lượng, và 2 giờ với matcher.group (1); matcher.group (2); matcher.group (3);

+0

Bạn có thể hiển thị mã của mình không? Điều đó nên phù hợp với 06:30, cung cấp mọi thứ khác là theo thứ tự. –

Trả lời

36

Chức năng matcher.group() dự kiến ​​sẽ lấy một đối số nguyên duy nhất: Chỉ mục nhóm chụp, bắt đầu từ 1. Chỉ mục 0 là đặc biệt, có nghĩa là "toàn bộ kết quả phù hợp". Nhóm chụp được tạo bằng cách sử dụng một cặp dấu ngoặc đơn "(...)". Mọi thứ trong ngoặc đơn đều được chụp. Các nhóm được đánh số từ trái sang phải (một lần nữa, bắt đầu từ 1), bằng cách mở dấu ngoặc đơn (có nghĩa là các nhóm có thể trùng lặp). Vì không có dấu ngoặc đơn trong cụm từ thông dụng của bạn nên không thể có nhóm 1.

javadoc trên lớp Pattern bao gồm cú pháp biểu thức chính quy.

Nếu bạn đang tìm mẫu có thể lặp lại một số lần, bạn có thể sử dụng Matcher.find() nhiều lần cho đến khi nó trả về sai. Matcher.group(0) một lần trên mỗi lần lặp lại sau đó sẽ trả về những gì phù hợp với thời gian đó.

Nếu bạn muốn xây dựng một biểu thức chính quy lớn phù hợp với mọi thứ cùng một lúc (mà tôi tin là những gì bạn muốn), sau đó xoay quanh từng bộ ba thứ bạn muốn chụp, đặt một bộ chụp dấu ngoặc đơn, sử dụng Matcher.match() và sau đó là Matcher.group(n) trong đó n là 1, 2 và 3 tương ứng. Tất nhiên Matcher.match() cũng có thể trả về false, trong trường hợp đó mẫu không khớp, và bạn không thể truy xuất bất kỳ nhóm nào.

Trong ví dụ của bạn, những gì bạn có thể muốn làm là nó khớp với một số văn bản trước đó, sau đó bắt đầu nhóm chụp, đối sánh chữ số, kết thúc nhóm chụp, v.v. Tôi không biết đủ về chính xác của bạn định dạng đầu vào, nhưng đây là một ví dụ.

phép nói rằng tôi đã có chuỗi có dạng:

Eat 12 carrots at 12:30 
Take 3 pills at 01:15 

Và tôi muốn trích xuất số lượng và thời gian.biểu hiện thường xuyên của tôi sẽ giống như thế:

"\w+ (\d+) [\w ]+ (\d{1,2}:\d{2})" 

Mã sẽ giống như thế:

Pattern p = Pattern.compile("\\w+ (\\d+) [\\w ]+ (\\d{2}:\\d{2})"); 
Matcher m = p.matcher(oneline); 
if(m.matches()) { 
    System.out.println("The quantity is " + m.group(1)); 
    System.out.println("The time is " + m.group(2)); 
} 

Các biểu hiện thường xuyên có nghĩa là "một chuỗi có chứa một từ, một không gian, một hoặc nhiều chữ số (mà là được chụp trong nhóm 1), một khoảng trắng, một tập hợp các từ và dấu cách kết thúc bằng dấu cách, theo sau là một thời gian (được chụp trong nhóm 2 và thời gian giả định rằng giờ đó luôn luôn là 0-đệm thành 2 chữ số). một ví dụ gần hơn với những gì bạn đang tìm kiếm, nhưng mô tả về đầu vào có thể là một chút mơ hồ.

+1

Cảm ơn bạn Adam, tôi đã khá bối rối với Matcher API – mickthompson

+1

Xin chào Adam, định dạng đầu vào của tôi luôn giống nhau. Tôi cần trích xuất 2 giờ và số sau chuỗi XX ~ (1234 trong trường hợp của ví dụ). Con số đó có thể là {3,4} chữ số. – mickthompson

+4

Hy vọng điều này sẽ giúp người khác. Bạn ** cần ** gọi 'm.matches()' (hoặc 'm.find()') trước khi bạn gọi hàm m.group(), nếu không nó sẽ nói không có bất kỳ kết quả nào (vì nó không hãy tìm bất kỳ điều gì), ít nhất đây là những gì xảy ra trên Android. –