Odpowiedzi:
Powinieneś móc używać niechciwych kwantyfikatorów, a konkretnie * ?. Prawdopodobnie będziesz potrzebować następujących rzeczy:
Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");
To da ci wzór, który będzie pasował do twojego ciągu i umieści tekst w nawiasach kwadratowych w pierwszej grupie. Zapoznaj się z dokumentacją Pattern API, aby uzyskać więcej informacji.
Aby wyodrębnić ciąg, możesz użyć czegoś takiego:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
sposób bez wyrażeń regularnych:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
alternatywnie, dla nieco lepszej wydajności / wykorzystania pamięci (dzięki Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')
zamiast, który będzie obsługiwać nawiasów zagnieżdżonych. Ponadto uważam, że użycie programu indexOf(char)
byłoby szybsze niż indexOf(String)
.
lastIndexOf
z pewnością szybciej będzie znaleźć nawias zamykający.
Oto działający przykład:
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);
}
}
}
To pokazuje :
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]
Jeśli po prostu potrzebujesz zdobyć to, co jest pomiędzy []
, możesz użyć w \[([^\]]*)\]
następujący sposób:
Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
result = m.group();
}
Jeśli chcesz, aby był w formie identifier + [ + content + ]
, możesz ograniczyć wyodrębnianie treści tylko wtedy, gdy identyfikator jest alfanumeryczny:
[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
Pozwoli to zweryfikować takie rzeczy Foo [Bar]
, albo myDevice_123["input"]
na przykład.
Główna kwestia
Główny problem występuje, gdy chcesz wyodrębnić zawartość czegoś takiego:
FOO[BAR[CAT[123]]+DOG[FOO]]
Regex nie będzie działać i wróci BAR[CAT[123
i FOO
.
Jeśli zmienimy Regex na, \[(.*)\]
wszystko jest w porządku, ale jeśli próbujesz wyodrębnić zawartość z bardziej złożonych rzeczy, takich jak:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
Żaden z Regexów nie zadziała.
Najdokładniejszy Regex do wyodrębnienia właściwej treści we wszystkich przypadkach byłby znacznie bardziej złożony, ponieważ musiałby zrównoważyć []
pary i zapewnić ich zawartość.
Prostsze rozwiązanie
Jeśli twoje problemy stają się coraz bardziej złożone, a zawartość jest []
arbitralna, możesz zamiast tego zrównoważyć pary []
i wyodrębnić ciąg przy użyciu zwykłego starego kodu zamiast 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;
}
To jest bardziej pseudokod niż prawdziwy kod, nie jestem koderem Java, więc nie wiem, czy składnia jest poprawna, ale powinno być wystarczająco łatwe do ulepszenia.
Liczy się to, że ten kod powinien działać i pozwalać na wyodrębnienie zawartości []
, jakkolwiek jest to skomplikowane.
Myślę, że twoje wyrażenie regularne wyglądałoby tak:
/FOO\[(.+)\]/
Zakładając, że inspektor obsługi lotów będzie stały.
Tak więc, aby umieścić to w Javie:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));
To zwróci wartość między pierwszym „[” a ostatnim „]”
Foo [Bar] => Bar
Foo [Bar [test]] => Bar [test]
Uwaga: należy dodać funkcję sprawdzania błędów, jeśli ciąg wejściowy nie jest poprawnie sformułowany.
Zdefiniowałbym, że chcę mieć maksymalną liczbę znaków innych niż] między [
a ]
. Muszą być one poprzedzone odwrotnym ukośnikiem (aw Javie trzeba je ponownie zmienić), a definicja non-] jest klasą znaków, a więc wewnątrz [
i ]
(tj [^\\]]
.). Wynik:
FOO\\[([^\\]]+)\\]
W ten sposób jego praca, jeśli chcesz przeanalizować jakiś ciąg, który pochodzi z mYearInDB.toString () = [2013], da 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);
To wyrażenie regularne działa dla mnie:
form\[([^']*?)\]
przykład:
form[company_details][0][name]
form[company_details][0][common_names][1][title]
wynik:
Match 1
1. company_details
Match 2
1. company_details
Przetestowano na http://rubular.com/
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
Spowoduje to zwrócenie łańcucha zawierającego tylko ciąg w nawiasach kwadratowych.
Spowoduje to usunięcie całego ciągu na zewnątrz z nawiasów kwadratowych.
Możesz przetestować ten przykładowy kod java online: http://tpcg.io/wZoFu0
Możesz przetestować to wyrażenie regularne tutaj: https://regex101.com/r/oUAzsS/1