Risposte:
Dovresti essere in grado di utilizzare quantificatori non avidi, in particolare * ?. Probabilmente vorrai quanto segue:
Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");
Questo ti darà uno schema che corrisponderà alla tua stringa e inserirà il testo tra parentesi quadre nel primo gruppo. Dai un'occhiata alla Documentazione API Pattern per ulteriori informazioni.
Per estrarre la stringa, è possibile utilizzare qualcosa di simile al seguente:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
il modo non regex:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
in alternativa, per prestazioni / utilizzo della memoria leggermente migliori (grazie a Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')
invece utilizzare , che gestirà parentesi annidate. Inoltre, credo che usare il indexOf(char)
sarebbe più veloce di indexOf(String)
.
lastIndexOf
sarà sicuramente più veloce trovare la parentesi di chiusura.
Questo è un esempio funzionante:
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);
}
}
}
Visualizza:
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]
Se hai semplicemente bisogno di ottenere qualsiasi cosa sia tra []
, puoi usare in \[([^\]]*)\]
questo modo:
Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
result = m.group();
}
Se è necessario che sia del modulo, identifier + [ + content + ]
è possibile limitare l'estrazione del contenuto solo quando l'identificatore è alfanumerico:
[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
Ciò convaliderà cose come Foo [Bar]
, o myDevice_123["input"]
per esempio.
Problema principale
Il problema principale è quando vuoi estrarre il contenuto di qualcosa del genere:
FOO[BAR[CAT[123]]+DOG[FOO]]
Il Regex non funzionerà e tornerà BAR[CAT[123
e FOO
.
Se cambiamo Regex in \[(.*)\]
allora siamo a posto ma, se stai cercando di estrarre il contenuto da cose più complesse come:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
Nessuno dei Regex funzionerà.
Il Regex più accurato per estrarre il contenuto corretto in tutti i casi sarebbe molto più complesso in quanto dovrebbe bilanciare le []
coppie e darti il loro contenuto.
Una soluzione più semplice
Se i tuoi problemi stanno diventando complessi e il contenuto []
dell'arbitrario, potresti invece bilanciare le coppie di []
ed estrarre la stringa usando semplicemente il vecchio codice rathe di un 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;
}
Questo è più pseudo-codice che codice reale, non sono un programmatore Java quindi non so se la sintassi è corretta, ma dovrebbe essere abbastanza facile da migliorare.
Ciò che conta è che questo codice dovrebbe funzionare e permetterti di estrarre il contenuto di []
, per quanto complesso sia.
Penso che la tua espressione regolare sarebbe simile a:
/FOO\[(.+)\]/
Supponendo che l'UFAM sarà costante.
Quindi, per dirlo in Java:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));
Questo restituirà il valore tra il primo '[' e l'ultimo ']'
Foo [Bar] => Bar
Foo [Bar [test]] => Bar [test]
Nota: è necessario aggiungere un errore verificando se la stringa di input non è ben formata.
Definirei che desidero un numero massimo di caratteri non] tra [
e ]
. Questi devono essere sfuggiti alle barre rovesciate (e in Java, questi devono essere sfuggiti di nuovo), e la definizione di non-] è una classe di caratteri, quindi dentro [
e ]
(cioè [^\\]]
). Il risultato:
FOO\\[([^\\]]+)\\]
In questo modo funziona se si desidera analizzare alcune stringhe che provengono da mYearInDB.toString () = [2013], darà 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);
Questo regexp funziona per me:
form\[([^']*?)\]
esempio:
form[company_details][0][name]
form[company_details][0][common_names][1][title]
produzione:
Match 1
1. company_details
Match 2
1. company_details
Testato su http://rubular.com/
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
Questo restituirà una stringa che prende solo la stringa tra parentesi quadre.
Questo rimuove tutta la stringa esterna dalle parentesi quadre.
Puoi testare questo codice di esempio java online: http://tpcg.io/wZoFu0
Puoi provare questo regex da qui: https://regex101.com/r/oUAzsS/1