2012-12-19 14 views
7

Eventuali duplicati:
How to get function parameter names/values dynamically from javascriptespressioni regolari per ottenere la lista dei parametri da definizione di funzione

Attualmente sto lavorando su un progetto in javascript (node.js) che ha me cercando di ottenere un array di parametri nomi (valori NON, non ho bisogno di argomenti) da una funzione. Attualmente sto usando Function.toString() per ottenere la stringa di funzione e quindi eseguire una regex su quella per ottenere la mia lista di parametri.

Prendiamo il seguente semplice esempio:

var myFunction = function (paramOne, paramTwo) { ... } 

esecuzione il mio regex contro questo, e poi fare qualche magia stringa (split, ecc) mi aspetterei un allineamento indietro come questo:

paramList = ['paramOne', 'paramTwo'] 

Ho qualcosa che funziona ma mi sento come se probabilmente non fosse la soluzione migliore dato alcuni dei caratteri funky che javascript consente di usare per nomi variabili e che javascript ti consente di definire le funzioni su più righe.

Ecco quello che ho attualmente:

function.*[\w\s$]*(\((.*[\w\s,$]*)\)) 

Questo mi dà il mio "match" nel gruppo 1 e poi la mia lista param senza parentesi nel gruppo 2, che è fresco. È davvero il modo migliore per fare ciò che voglio? C'è una migliore espressione regolare che potrei usare per questo? Non cerco davvero qualcosa di "più semplice", ma davvero qualcosa che possa cogliere tutte le possibili situazioni.

Qualsiasi aiuto sarebbe apprezzato, e molte grazie in anticipo!

risposta

16

La cosa più semplice sarebbe catturare tutto nel primo set di parentesi e quindi utilizzare split(/\s*,\s*/) per ottenere l'array.

Esempio:

var str = "function( one ,\ntwo,three , four ) { laksjdfl akjsdflkasjdfl }"; 
 
var args = /\(\s*([^)]+?)\s*\)/.exec(str); 
 
if (args[1]) { 
 
    args = args[1].split(/\s*,\s*/); 
 
} 
 
snippet.log("args: " + JSON.stringify(args));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Come le opere di cui sopra:

  1. Usiamo /\(*([^)]+?) *\)/ per abbinare la prima parentesi di apertura (\( dal ( è speciale in espressioni regolari), seguito da qualsiasi quantità di spazi bianchi facoltativi, seguita da un gruppo di cattura c aprendo tutto tranne una parentesi chiusa (ma non golosa), seguita da una qualsiasi quantità di spazi bianchi facoltativi, seguita dalla chiusura ).

  2. Se ci riusciamo, abbiamo diviso utilizzando /\s*,\s*/, il che significa che abbiamo diviso in sequenze che sono zero o più caratteri di spaziatura (\s*) seguito da una virgola seguita da zero o più caratteri di spaziatura (questa cosa spazi ecco perché i args in la mia funzione di esempio è così strana).

Come si può vedere dall'esempio, questo gestisce gli spazi restanti (dopo la ( e prima che il primo argomento), gli spazi bianchi attorno alle virgole e spazi finali   — tra cui interruzioni di riga. È non provare a gestire i commenti all'interno dell'elenco degli argomenti, il che complicherebbe notevolmente le cose.


Nota a margine: Assicurati di testare il browser di destinazione, Function#toString tornando qualche forma di codice sorgente è una caratteristica non standard. È ampiamente supportato (nei browser desktop), ma non standard. Nota che alcuni browser includeranno commenti, altri no; se qualcuno include commenti negli argomenti della funzione, potrebbe rovinare il tuo parsing di essi. Si potrebbe calci in tutto il Prototype source code for its Function#argumentNames extension, come hanno già stati su questa strada ...

+0

Come pensi che dovrei andare a riguardo? Questo è quello che sto cercando di fare con il mio regex, ma forse c'è un approccio diverso? Stai pensando che potrei solo indexOf "(" e ")" e poi dividere cosa c'è in mezzo? Sarebbe meglio di una regex pazza? –

+0

@JasonL .: Ho aggiunto del codice alla risposta (e un esempio dal vivo). –

+0

Grazie! La tua soluzione è molto più semplice di quanto pensassi mi aspettassi. Al momento sto provando con tutte le diverse varianti consentite da javascript. Ciò consentirà di catturare tutti i pazzi personaggi speciali consentiti da javascript (uno dei più famosi è l'aspetto di disapprovazione)? Si noti anche che questo è per l'ambiente node.js SOLO, quindi ho davvero solo bisogno di preoccuparsi V8 :) –

3

Do come segue:

var ar = str.match(/\((.*?)\)/); 
if (ar) { 
    var result = ar[0].split(","); 
} 

Ricordate? dopo * fa un non avido trovare

2

Fammi suggerisco di utilizzare le espressioni regolari:

  • [partita] /function[^(]*\(([^)]*)\)/ corrisponderà la lista degli argomenti
  • [SPLIT] /\W+/ (contro i risultati dei primi dati partita) per suddividere la partita nella lista params

Quindi, il codice dovrebbe essere simile a questo:

var s = "function moo (paramOne, paramTwo) { alert('hello'); }"; 
var s2 = s.match(/function[^(]*\(([^)]*)\)/)[1]; 
var paramList = s2.split(/\W+/); 
+0

Cool, buon lavoro +1 – iConnor

Problemi correlati