Câu trả lời:
Bạn sẽ có thể sử dụng các bộ lượng hóa không tham lam, cụ thể là *?. Bạn sẽ có thể muốn như sau:
Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");
Điều này sẽ cung cấp cho bạn một mẫu sẽ khớp với chuỗi của bạn và đặt văn bản trong dấu ngoặc vuông trong nhóm đầu tiên. Hãy xem Tài liệu API mẫu để biết thêm thông tin.
Để trích xuất chuỗi, bạn có thể sử dụng một cái gì đó như sau:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
cách không regex:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
cách khác, để sử dụng hiệu năng / bộ nhớ tốt hơn một chút (cảm ơn Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')
thay thế, mà sẽ xử lý dấu ngoặc lồng. Ngoài ra, tôi tin rằng việc sử dụng indexOf(char)
sẽ nhanh hơn indexOf(String)
.
lastIndexOf
chắc chắn sẽ nhanh hơn để tìm khung đóng cửa.
Đây là một ví dụ hoạt động:
RegapiExample.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ó sẽ hiển thị :
value1
value2
value3
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]
Nếu bạn chỉ cần lấy bất cứ thứ gì ở giữa []
, 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ó phải ở dạng identifier + [ + content + ]
thì bạn chỉ có thể giới hạn trích xuất nội dung khi mã định danh là một chữ số:
[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
Điều này sẽ xác nhận những thứ như Foo [Bar]
, hoặc myDevice_123["input"]
ví dụ.
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]]
Regex sẽ không hoạt động và sẽ trở lại BAR[CAT[123
và FOO
.
Nếu chúng tôi thay đổi Regex thành \[(.*)\]
thì chúng tôi sẽ ổn nhưng sau đó, nếu bạn đang cố trích xuất nội dung từ những thứ phức tạp hơn như:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
Không có Regexes nào hoạt động.
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ì nó cần phải cân bằng []
các cặp và cung cấp cho bạn nội dung chúng.
Một giải pháp đơn giản hơn
Nếu các vấn đề của bạn trở nên phức tạp và nội dung []
tùy ý, thay vào đó, bạn có thể cân bằng các cặp []
và trích xuất chuỗi bằng cách sử dụng mã cũ đơn giản hơn so với 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ả nhiều hơn mã thực, tôi không phải là người viết mã Java nên tôi không biết cú pháp có đúng không, nhưng nó đủ dễ để cải thiện.
Điều quan trọng là mã này sẽ hoạt động và cho phép bạn trích xuất nội dung của nó []
, tuy nhiên nó phức tạp.
Tôi nghĩ rằng biểu hiện thường xuyên của bạn sẽ trông như sau:
/FOO\[(.+)\]/
Giả sử rằng FOO sẽ không đổi.
Vì vậy, để đưa cái này vào Java:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));
Điều này sẽ trả về giá trị giữa đầu tiên '[' và cuối ']'
Foo [Thanh] => Thanh
Foo [Thanh [kiểm tra]] => Thanh [kiểm tra]
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 tốt.
Tôi xác định rằng tôi muốn số lượng ký tự không tối đa giữa [
và ]
. Những cái này cần phải được thoát bằng dấu gạch chéo ngược (và trong Java, những cái này cần phải được thoát lại một lần nữa) và định nghĩa của non-] là một lớp ký tự, do đó bên trong [
và ]
(nghĩa là [^\\]]
). Kết quả:
FOO\\[([^\\]]+)\\]
Giống như nó hoạt động nếu bạn muốn phân tích một số chuỗi đến từ mYearInDB.toString () = [2013], nó sẽ cung cấp cho năm 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);
Regrec này hoạt động với tôi:
form\[([^']*?)\]
thí 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/
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
Điều này sẽ trả về một chuỗi chỉ lấy chuỗi bên trong dấu ngoặc vuông.
Điều này loại bỏ tất cả các chuỗi bên ngoài từ dấu ngoặc vuông.
Bạn có thể kiểm tra mã mẫu java này trực tuyến: http://tpcg.io/wZoFu0
Bạn có thể kiểm tra regex này từ đây: https://regex101.com/r/oUAzsS/1