Відповіді:
Ви повинні мати можливість використовувати не жадібні квантори, зокрема * ?. Ви, ймовірно, хочете наступного:
Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");
Це дасть вам шаблон, який буде відповідати вашому рядку і помістить текст у квадратні дужки у першій групі. Перегляньте Документацію API API для отримання додаткової інформації.
Щоб витягти рядок, ви можете використовувати щось на зразок наступного:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
нерегекс-спосіб:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
або для дещо кращої продуктивності / використання пам'яті (спасибі Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')замість цього, який би обробляв вкладені дужки. Крім того, я вважаю, що використання цього indexOf(char)було б швидше, ніж indexOf(String).
lastIndexOf, безумовно, буде швидше знайти дужку закриття.
Це робочий приклад:
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);
}
}
}
На ньому відображаються:
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]
Якщо вам просто потрібно отримати все, що між ними [], ви можете використовувати \[([^\]]*)\]так:
Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
result = m.group();
}
Якщо вам потрібно мати форму, identifier + [ + content + ]ви можете обмежити вилучення вмісту лише тоді, коли ідентифікатор буквено-цифровий:
[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
Це підтвердить такі речі, як Foo [Bar], myDevice_123["input"]наприклад,.
Основне питання
Основна проблема полягає в тому, коли ви хочете витягнути вміст чогось подібного:
FOO[BAR[CAT[123]]+DOG[FOO]]
Regex не працюватиме і повернеться BAR[CAT[123і FOO.
Якщо ми змінимо Regex, \[(.*)\]тоді ми все в порядку, але тоді, якщо ви намагаєтеся витягнути вміст із складніших речей, таких як:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
Жоден з Regexes не буде працювати.
Найбільш точний Regex для вилучення належного вмісту у всіх випадках був би набагато складнішим, оскільки потрібно було б збалансувати []пари та дати їм вміст.
Більш просте рішення
Якщо ваші проблеми ускладнюються, а вміст []довільний, ви можете замість цього збалансувати пари []та витягнути рядок, використовуючи звичайний старий код коду, ніж 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;
}
Це більше псевдо-код, ніж реальний код, я не кодер Java, тому не знаю, чи правильний синтаксис, але це повинно бути досить легким для вдосконалення.
Що враховує, що цей код повинен працювати і дозволяти витягувати вміст [], як би він не був складним.
Я думаю, що ваш регулярний вираз виглядатиме так:
/FOO\[(.+)\]/
Припускаючи, що FOO буде постійним.
Отже, щоб сказати це на Java:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));
Це поверне значення між першим '[' та останнім ']'
Foo [Bar] => Бар
Foo [Бар [тест]] => Панель [тест]
Примітка. Ви повинні додати перевірку помилок, якщо вхідний рядок не сформований належним чином.
Я б визначив, що мені потрібно максимальну кількість символів, що не] між [та ]. Їх потрібно уникнути за допомогою косої риски (і на Java, їх потрібно уникнути знову), а визначення non-] є класом символів, таким чином, всередині [і ](тобто [^\\]]). Результат:
FOO\\[([^\\]]+)\\]
Подобається це його роботі, якщо ви хочете проаналізувати деякий рядок, який надходить від mYearInDB.toString () = [2013], він дасть 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);
Цей регепс працює для мене:
form\[([^']*?)\]
приклад:
form[company_details][0][name]
form[company_details][0][common_names][1][title]
вихід:
Match 1
1. company_details
Match 2
1. company_details
Тестовано на http://rubular.com/
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
Це поверне рядок із лише рядком всередині квадратних дужок.
Це видалить всю рядок зовні з квадратних дужок.
Ви можете перевірити цей зразок коду Java онлайн: http://tpcg.io/wZoFu0
Ви можете протестувати цей регекс звідси: https://regex101.com/r/oUAzsS/1