Dividere lo script testuali in sottostringhe di modello
-
30-09-2019 - |
Domanda
Si consideri seguente script (è una sciocchezza totale nella pseudo-lingua):
if (Request.hostMatch("asfasfasf.com") && someString.existsIn(new String[] {"brr", "hrr"})) {
if (Requqest.clientIp("10.0.x.x")) {
somevar = "1";
}
somevar = "2";
}
else {
somevar = "first";
}
string foo = "foo";
// etc. etc.
Come vi afferrare se-block parametri e contenuti da esso è? Il se-blocco ha formato:
if<whitespace>(<parameters>)<whitespace>{<contents>}<anything>
Ho provato ad utilizzare String.split()
con schema di espressione regolare di ^if\s*\(|\)\s*\{|\}\s*
ma questo fallisce miseramente. Vale a dire, il problema è che ) {
si trova anche in interno se-blocco e la }
chiusura è situato molti posti. Non credo che né l'espansione pigri o desiderosi lavora qui.
Quindi ... tutti i puntatori a ciò che potrebbe ho bisogno qui al fine di attuare questo con regex?
Ho anche bisogno di ottenere la stringa di rimanere senza il codice del se-blocco (in modo di codice a partire dal else { ...
). Utilizzando solo String.split()
sembra rendere difficile in quanto non vi sono informazioni circa la lunghezza delle parti che sono state analizzate via.
I inizialmente creato una soluzione basata loop (utilizzando String.substring()
pesantemente) per questo, ma è noioso. Mi piacerebbe avere qualcosa di più elaborato, invece. Dovrei andare con regex o creare un personalizzati, funzione generica (ci sono molti altri casi che solo questo) che prende il parseable String e il modello invece (in considerazione il modello di if<whitespace>(...
sopra)?
Modifica :. Senso ritorna cambiato in assegnazioni di variabili in quanto avrebbero fatto altrimenti non
Soluzione
Un linguaggio normale non funzionerà perché un regolare grammatica può non corrispondere le cose come " qualsiasi numero di parentesi aperta seguita da un numero qualsiasi di parentesi chiusa". Un grammatica context-free sarebbero necessari per questo .
A meno che non si utilizza un context-free grammar parser per un'estensione di espressione regolare che Java o < a href = "http://www.truerwords.net/5711" rel = "nofollow"> rende le espressioni regolari non è più regolare , la soluzione basata su loop è probabilmente la soluzione più fantastica.
Altri suggerimenti
Si sarebbe molto meglio utilizzare (o scrivere) un parser che cercare di farlo con Regex.
Regex è grande per la quarantina, ma per l'analisi complesso come questo, fa schifo. Un altro esempio in cui mi fa schifo che viene chiesto molto qui è parsing del codice HTML -. Si può fare in misura limitata, ma per nulla complesso, un parser DOM è una soluzione molto migliore
Per un [molto] parser semplice, quello che vi serve è una funzione ricorsiva che cerca una parentesi {
e }
, recursing giù di un livello ogni volta che rileva una parentesi di apertura, e tornando indietro di un livello quando si trova un chiusura brace. Si deve quindi memorizzare il contenuto della stringa tra i due ganci ad ogni livello.
Come per il precedente, avrete bisogno di un parser. Un tipo che è facile da implementare (e divertente da scrivere!) È un ricorsiva discesa parser con backtracking . C'è anche una pletora di generatori di parser là fuori, se la maggior parte di coloro che hanno una curva di apprendimento. Un generatore di parser Java-friendly è JavaCC .