2009-03-01 32 views

Trả lời

212

Bạn sẽ có thể sử dụng định lượng không tham lam, cụ thể * ?. Bạn có thể sẽ muốn như sau:

Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]"); 

Điều này sẽ cung cấp cho bạn mẫu phù hợp với chuỗi và đặt văn bản trong dấu ngoặc vuông trong nhóm đầu tiên. Hãy xem qua số Pattern API Documentation để biết thêm thông tin.

Để trích xuất các chuỗi, bạn có thể sử dụng giống như sau:

Matcher m = MY_PATTERN.matcher("FOO[BAR]"); 
while (m.find()) { 
    String s = m.group(1); 
    // s now contains "BAR" 
} 
+13

Điều đáng nói đến là nếu có một dòng mới giữa các dấu ngoặc vuông, điều này sẽ thất bại và bạn nên sử dụng cờ Pattern.DOTALL để tránh điều đó. – cletus

+0

Sử dụng mẫu ở trên, sau đó bạn sẽ sử dụng mẫu đó để trích xuất chuỗi chứa chuỗi BAR? Tôi đang xem API mẫu và API của Matcher nhưng tôi vẫn không chắc chắn làm thế nào để có được chuỗi đó. – digiarnie

+0

@cletus: Cuộc gọi tốt! @digiarnie: Tôi đã thêm bản sửa đổi cho câu trả lời có chứa một số mã rơm-man để nhận được trận đấu. –

29

cách phi regex:

String input = "FOO[BAR]", extracted; 
extracted = input.substring(input.indexOf("["),input.indexOf("]")); 

cách khác, cho hiệu suất/sử dụng bộ nhớ tốt hơn một chút (nhờ Hosam) :

String input = "FOO[BAR]", extracted; 
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']')); 
+1

Tôi sẽ sử dụng 'lastIndexOf (']')' thay vào đó, sẽ xử lý các dấu ngoặc lồng nhau. Ngoài ra, tôi tin rằng việc sử dụng 'indexOf (char)' sẽ nhanh hơn 'indexOf (String)'. –

+0

đã đồng ý, tôi sẽ thêm một bản chỉnh sửa – zaczap

+0

Bạn được chào đón. Lưu ý của bạn về hiệu suất cũng rất phù hợp, vì 'lastIndexOf' chắc chắn sẽ nhanh hơn để tìm khung đóng. –

2

Tôi nghĩ cụm từ thông dụng của bạn sẽ trông giống như:

/FOO\[(.+)\]/ 

Giả sử rằng FOO sẽ không đổi.

Vì vậy, để đặt điều này trong Java:

Pattern p = Pattern.compile("FOO\\[(.+)\\]"); 
Matcher m = p.matcher(inputLine); 
+0

FOO [BAR] FOO [BAZ] -> với regex của bạn sẽ trả về: "BAR] FOO [BAZ" –

0

giả định rằng không có đóng khung vuông khác được phép bên trong,/FOO \ [([^ \]] *) \]/

0

tôi 'd xác định rằng tôi muốn có tối đa số ký tự không phải là] giữa []. Những điều này cần phải được thoát bằng dấu gạch chéo ngược (và trong Java, những thứ này cần phải được thoát ra lần nữa) và định nghĩa của non-] là một lớp ký tự, do đó, bên trong [] (ví dụ: [^\\]]). Kết quả:

FOO\\[([^\\]]+)\\] 
5

Nếu bạn chỉ đơn giản là cần phải nhận được bất cứ điều gì là giữa [], các bạn có thể sử dụng \[([^\]]*)\] như thế này:

Pattern regex = Pattern.compile("\\[([^\\]]*)\\]"); 
Matcher m = regex.matcher(str); 
if (m.find()) { 
    result = m.group(); 
} 

Nếu bạn cần nó để có dạng identifier + [ + content + ] sau đó bạn có thể giới hạn trích xuất nội dung chỉ khi số nhận dạng là chữ và số:

[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\] 

Điều này sẽ valida ví dụ như số điện thoại Foo [Bar] hoặc myDevice_123["input"].

vấn đề chính

Vấn đề chính là khi bạn muốn trích xuất nội dung của một cái gì đó như thế này:

FOO[BAR[CAT[123]]+DOG[FOO]] 

Các Regex sẽ không hoạt động và sẽ trở lại BAR[CAT[123FOO.
Nếu chúng ta thay đổi Regex để \[(.*)\] sau đó chúng tôi OK nhưng sau đó, nếu bạn đang cố gắng để trích xuất nội dung từ những điều phức tạp hơn như:

FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]] 

Không ai trong số các Regexes sẽ làm việc.

Regex chính xác nhất để trích xuất nội dung phù hợp trong mọi trường hợp sẽ phức tạp hơn rất nhiều vì cần cân bằng các cặp [] và cung cấp cho bạn nội dung đó.

Một giải pháp đơn giản hơn

Nếu vấn đề của bạn là nhận phức tạp và nội dung của [] tùy ý, bạn thay vì có thể cân bằng cặp [] và trích xuất các chuỗi sử dụng đồng bằng đang nở sớm già hơn một Regex:

int i; 
int brackets = 0; 
string c; 
result = ""; 
for (i = input.indexOf("["); i < str.length; i++) { 
    c = str.substring(i, i + 1); 
    if (c == '[') { 
     brackets++; 
    } else if (c == ']') { 
     brackets--; 
     if (brackets <= 0) 
      break; 
    } 
    result = result + c; 
} 

Đây là mã giả hơn mã thực, tôi không phải là người lập trình Java nên tôi không biết cú pháp có chính xác hay không, nhưng phải dễ dàng cải thiện.
Số lượng mã này sẽ hoạt động và cho phép bạn trích xuất nội dung của số [], tuy nhiên nó phức tạp.

1
String input = "FOO[BAR]"; 
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]")); 

này sẽ trả về giá trị giữa đầu tiên '[' và cuối cùng ']'

Foo [Bar] => Bar

Foo [Bar [thử nghiệm]] => Bar [thử nghiệm]

Lưu ý: Bạn nên thêm kiểm tra lỗi nếu chuỗi đầu vào không được định dạng đúng.

17

Đây là một ví dụ làm việc:

RegexpExample.java

package org.regexp.replace; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class RegexpExample 
{ 
    public static void main(String[] args) 
    { 
     String string = "var1[value1], var2[value2], var3[value3]"; 
     Pattern pattern = Pattern.compile("(\\[)(.*?)(\\])"); 
     Matcher matcher = pattern.matcher(string); 

     List<String> listMatches = new ArrayList<String>(); 

     while(matcher.find()) 
     { 
      listMatches.add(matcher.group(2)); 
     } 

     for(String s : listMatches) 
     { 
      System.out.println(s); 
     } 
    } 
} 

Nó hiển thị:

value1 
value2 
value3 
0

Giống như công việc của mình này nếu bạn muốn phân tích một số chuỗi được đến từ mYearInDB .toString() = [năm 2013] nó sẽ cho 2013

Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString()); 
while (n.find()) { 
extracredYear = n.group(1); 
// s now contains "BAR" 
    } 
    System.out.println("Extrated output is : "+extracredYear); 
5
import java.util.*; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public static String get_match(String s, String p) { 
    // returns first match of p in s for first group in regular expression 
    Matcher m = Pattern.compile(p).matcher(s); 
    return m.find() ? m.group(1) : ""; 
} 

get_match("FOO[BAR]", "\\[(.*?)\\]") // returns "BAR" 

public static List<String> get_matches(String s, String p) { 
    // returns all matches of p in s for first group in regular expression 
    List<String> matches = new ArrayList<String>(); 
    Matcher m = Pattern.compile(p).matcher(s); 
    while(m.find()) { 
     matches.add(m.group(1)); 
    } 
    return matches; 
} 

get_matches("FOO[BAR] FOO[CAT]", "\\[(.*?)\\]")) // returns [BAR, CAT] 
0

công trình regexp này cho tôi:

form\[([^']*?)\] 

dụ:

form[company_details][0][name] 
form[company_details][0][common_names][1][title] 

đầu ra:

Match 1 
1. company_details 
Match 2 
1. company_details 

Thử nghiệm trên http://rubular.com/

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