Ultima modifica di andbin; 30-07-2015 a 16:07
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Ciao,
intanto grazie per l'attenzione che hai prestato al mio problema.
Una premessa che non ho fatto è che non sono alle prime armi di java, ma non mi considero nemmeno un programmatore esperto.
Cercherò comunque di risponderti, sperando di aver capito bene quello che mi chiedi.
La forma generale della mia espressione è la presenza di più triplette racchiuse tra apici, separate da virgola e a loro volta racchiuse tra parentesi quadre. L'espressione può contenere N triplette e tra di loro sono separate da operatori matematici )(+*/-.
esempi di possibili espressioni
['A1','B1','C1']+['A2','B2','C2']
o
['A1','B1','C1']+['A2','B2','C2']*(['A3','B3','C3']-['A2','B2','C2'])
...
In realtà in base a quello che mi chiedi non penso di avere un vero e proprio separatore che si ripete sempre, eccetto le quadre di apertura e chiusura tripletta. Di tutto il resto non me ne faccio nulla.
Alla fine vorrei ottenere un array che contiene le stringhe delle triplette.
Ottengo qualcosa di meglio con questo codice, anche se non mi sembra troppo "corretto":
e comunque l'array di risultato finale contiene dei valori vuoti:codice:public static void main(String[] args) { // TODO code application logic here String reg; String expression = "['0000000013','THUS|ETER','VALU']/(['0000000012','FPOD|VHFU','VALU']*['0000000137','PCO','GAS1'])"; reg = "[()-+*/]"; expression = expression.replaceAll(reg, ""); reg = "[\\[.*?\\]]"; String[] aExt = expression.split(reg); for (int i = 0; i < aExt.length; i++) { System.out.println("Tripletta: "+ aExt[i]); } }
Grazie ancoracodice:Tripletta: Tripletta: '0000000013','THUS|ETER','VALU' Tripletta: Tripletta: '0000000012','FPOD|VHFU','VALU' Tripletta: Tripletta: '0000000137','PCO','GAS1'
Ultima modifica di pikiuz; 30-07-2015 a 16:32
Cercando qua e la su internet sono riuscito ad arrivare a qualcosa del genere...mi rimane poi da creare l'array ma è la cosa meno complicata.
Quello che ancora non soro riuscito a fare e farlo lavorare con le [] piuttosto che con <<>>codice:public static void main(String [] argv) { String text = "<<'0000000013','THUS|ETER','VALU'>>/(<<'0000000012','FPOD|VHFU','VALU'>>*<<'0000000137','PCO','GAS1'>>)"; Pattern pattern = Pattern.compile("<<([^<<]+)>>"); Matcher matcher = pattern.matcher(text); while(matcher.find()) { System.out.println("Sottogruppo 1 : "+matcher.group(1)); } }
E' possibile?
Sì, la forma è chiara ora. Purtroppo non è banale, nel senso che è molto arbitraria cioè non c'è un pattern davvero rigoroso.
Potrei immaginare che siano anche possibili espressioni del tipo
[....]+([....]*([....]+[....]))
(dove "...." sono le 3 triplette, chiaramente)
Non è banale ... perché l'annidamento è arbitrario.
I separatori in realtà ci sono, li hai anche individuati tu cioè )(+*/- che sono gli operatori matematici più le parentesi tonde.
La mia domanda innanzitutto è: questi caratteri possono comparire dentro le triplette?
Se NON possono comparire, il mio approccio sarebbe questo:
1) Estraggo i token usando StringTokenizer configurato per restituire anche i delimitatori
Quindi da una stringa "['A1','B1','C1']+['A2','B2','C2']*(['A3','B3','C3']-['A2','B2','C2'])"
Otterrei 9 token:
"['A1','B1','C1']"
"+"
"['A2','B2','C2']"
"*"
"("
"['A3','B3','C3']"
"-"
"['A2','B2','C2']"
")"
2) Analizzo i token (non so se devi farlo tu...), quelli che non sono i separatori )(+*/- li analizzo singolarmente preferibilmente con una regex. Quindi per una stringa es. "['A3','B3','C3']" potrei usare una regex:
"\\['([^']+)','([^']+)','([^']+)'\\]"
(questa che ho scritto è già la String letterale, non la regex pura)
E con matches() posso innanzitutto verificare in modo "stretto" il formato, e se corrisponde, poi posso ottenere i dati della tripletta con i gruppi 1, 2 e 3.
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Ci sono riuscito, anche grazie a quanto hai suggerito te nella tue regex!
Quoto il codice:
Graziecodice:public static void main(String [] argv) { String text = "['0000000013','THUS|ETER','VALU']/(['0000000012','FPOD|VHFU','VALU']*['0000000137','PCO','GAS1'])"; Pattern pattern = Pattern.compile("\\[([^\\[]+)\\]"); Matcher matcher = pattern.matcher(text); while(matcher.find()) { System.out.println("Sottogruppo 1 : "+matcher.group(1)); } }
Se volevi solo trovare le occorrenze di [ ..... ] allora sì, basta 1 regex e il find().
Comunque la tua espressione non è correttissima. È più corretta:
"\\[([^\\]]+)\\]"
Il ^ all'inizio di una "classe" di caratteri [ ] serve a negare il senso. Quindi [^X]+ vuol dire una sequenza di 1 o più caratteri che non contiene X. In una sequenza ABCRGXFRG matcha solo ABCRG.
Pertanto la regex pura [^\]]+ vuol dire una sequenza che non contiene ']'. Questo serve per trovare più velocemente il ] di terminazione del tuo pattern, evitando che il motore delle regex vada a "consumare" subito tutto l'input causando poi backtracking se avessi usato es. .*
Insomma, è una ottimizzazione.
Ultima modifica di andbin; 30-07-2015 a 22:49
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Grazie ancora, seguirò sicuramente il tuo consiglio.Comunque la tua espressione non è correttissima. È più corretta:
"\\[([^\\]]+)\\]"