Utilizzo di Java per trovare la sottostringa di una stringa più grande utilizzando l’espressione regolare

Se ho una stringa come questa:

FOO[BAR] 

Ho bisogno di un modo generico per estrarre la stringa “BAR” dalla stringa in modo che, indipendentemente dalla stringa tra parentesi quadre, sia ansible ottenere la stringa.

per esempio

 FOO[DOG] = DOG FOO[CAT] = CAT 

Dovresti essere in grado di utilizzare quantificatori non grezzi, in particolare * ?. Probabilmente vorrai quanto segue:

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

Questo ti darà un modello che abbinerà la tua corda e metterà il testo tra parentesi quadre nel primo gruppo. Dai un’occhiata alla documentazione di Pattern API per maggiori informazioni.

Per estrarre la stringa, puoi usare qualcosa come la 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 leggermente migliori / utilizzo della memoria (grazie a Hosam):

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

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 listMatches = new ArrayList(); while(matcher.find()) { listMatches.add(matcher.group(2)); } for(String s : listMatches) { System.out.println(s); } } } 

Visualizza:

 value1 value2 value3 

Se hai semplicemente bisogno di ottenere ciò che è compreso tra [] , puoi usare \[([^\]]*)\] questo modo:

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

Se è necessario che sia identifier + [ + content + ] modulo identifier + [ + content + ] è ansible limitare l’estrazione del contenuto solo quando l’identificativo è alfanumerico:

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

Ciò valuterà 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 restituirà BAR[CAT[123 e FOO .
Se cambiamo il Regex in \[(.*)\] Allora siamo a posto, ma poi, 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 avrebbe bisogno di bilanciare [] coppie e darti il ​​loro contenuto.

Una soluzione più semplice

Se i tuoi problemi si stanno complicando e il contenuto della [] arbitraria, potresti bilanciare le coppie di [] ed estrarre la stringa usando un semplice codice vecchio anziché 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 codificatore Java, quindi non so se la syntax è corretta, ma dovrebbe essere abbastanza facile da migliorare.
Ciò che conta è che questo codice dovrebbe funzionare e consentire di estrarre il contenuto di [] , per quanto complesso esso sia.

 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 get_matches(String s, String p) { // returns all matches of p in s for first group in regular expression List matches = new ArrayList(); 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] 

Penso che la tua espressione regolare sarà simile a:

 /FOO\[(.+)\]/ 

Supponendo che FOO sarà costante.

Quindi, per inserire questo 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 controllo degli errori se la stringa di input non è ben formata.

supponendo che nessun’altra parentesi quadra di chiusura sia ammessa all’interno, / FOO \ [([^ \]] *) \] /

Definirei che voglio un numero massimo di caratteri non] tra [ e ] . Questi devono essere sfuggiti con i backslash (e in Java, questi devono essere nuovamente sottoposti a escape), e la definizione di non-] è una class di caratteri, quindi dentro [ e ] (cioè [^\\]] ). Il risultato:

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

Così funziona se vuoi analizzare una stringa che proviene 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/