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

È stato utile?

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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top