2012-08-11 4 views
5

Voglio corrispondere (selezionare dal file di classe) methodname, nome proprietà e nome campi.C# regex - seleziona i nomi delle proprietà di classe, il nome dei metodi ei campi dal file di classe (.cs)

Questo è esempio di classe:

class Perl 
{ 
    string _name; 
    public string Name { get; set; } 
    public Perl() 
    { 
    // Assign this._name 
    this._name = "Perl"; 
    // Assign _name 
    _name = "Sam"; 

    // The two forms reference the same field. 
    Console.WriteLine(this._name); 
    Console.WriteLine(_name); 
    } 
    public static string doSomething(string test) 
    { 
     bla test; 
    } 
} 

Ho codice per i metodi:

(?:public|private|protected)([\s\w]*)\s+(\w+)\s*\(\s*(?:\w+\s+(\w+)\s*,?\s*)+\) 

e ho avuto domande:

  • questo codice regex sopra ottiene tutti i metodi e lo funziona piuttosto bene ma anche io voglio che selezioni il nome del metodo ma senza parametri e accessori. Così dalla classe exaplmce usando il mio risultato il codice sarà: Perl pubblico() e doSomething public static (test string) ma voglio quel tipo di risultato: Perl() e doSomething(). Quindi - il mio codice corrisponde bene ma voglio che i risultati vengano visualizzati proprio come ho scritto io nella frase precedente.
  • come selezionare le proprietà? con risultato visualizzato: tipo e proprietà nome. Quindi dal risultato della classe di estrazione sarà: stringa Nome
  • come selezionare i campi con risultato: tipo nome_campo. Nel caso in cui fuori che sarà: stringa _name
+1

può essere duplicato di [questa risposta SO] (http://stackoverflow.com/a/11647554/1495442) – Ria

+0

Potrebbe essere utile utilizzare la riflessione sulla classe compilata anziché regex sul file di codice? Otterrai risultati molto più affidabili (ovvero non dovrai preoccuparti se il comando regex copre tutti i casi possibili) e potrebbe essere utilizzato con qualsiasi linguaggio .NET, non solo C#. –

+0

quindi ho la cartella con i file di classe .cs. Posso compilarlo "in aria" e quindi usare la riflessione? Come compilare la classe dinamicamente, ad esempio, esiste una funzione che posso usare? per esempio. sul pulsante fai clic su tutti i file cs nella cartella selezionata? – born2fr4g

risposta

3

Utilizzare questa Regex

per i metodi

(?:public\s|private\s|protected\s|internal\s)?[\s\w]*\s+(?<methodName>\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?<parameterType>\w+)\s+(?<parameter>\w+)\s*,?\s*)+\) 

e ottenere gruppi denominati methodName e parameterType e parameter.

e per i campi:

(?:public\s|private\s|protected\s)\s*(?:readonly\s+)?(?<type>\w+)\s+(?<name>\w+) 

e ottenere gruppi denominati type e name.

ad esempio il codice per i metodi può essere come questo:

var inputString0 = "public void test(string name, out int value)\r\nvoid test(string name, int value)"; 
foreach (Match match in Regex.Matches(inputString0, @"(?:public\s|private\s|protected\s)?[\s\w]*\s+(?<methodName>\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?<parameterType>[\w\?\[\]]+)\s+(?<parameter>\w+)\s*,?\s*)+\)")) 
{ 
    var methodName = match.Groups["methodName"].Value; 
    var typeParameterPair = new Dictionary<string, string>(); 
    int i = 0; 
    foreach (var capture in match.Groups["parameterType"].Captures) 
    { 
     typeParameterPair.Add(match.Groups["parameterType"].Captures[i].Value, match.Groups["parameter"].Captures[i].Value); 
     i++; 
    } 
} 

È possibile utilizzare Irony - .NET Language Implementation Kit da CodePlex troppo.

+0

ma per quanto riguarda proprietà e campi? ;) – born2fr4g

+0

per quanto riguarda l'ambito di visibilità 'internal'? –

+0

Non posso usare l'ironia;). Sto usando NET 2.0 nella mia applicazione. Grazie per il codice regex dei campi. Proverò a modificarlo per abbinare le proprietà (con get o set all'interno ** {} **) – born2fr4g

2

Come indicato nei commenti alla tua risposta, molto più affidabile metodo è quello di compilare i file Cs e quindi utilizzare la riflessione per interrogare tipi per i membri a cui è interessato che coinvolgerà la seguente:.

  1. Usa Compilatore C# (csc.exe) per compilare i tuoi file. MSDN contiene examples and hints utile. È possibile farlo manualmente o, se si desidera automatizzare l'intera operazione, è possibile eseguire csc.exe in modo programmatico con Process class.
  2. Utilizzare il metodo Assembly.LoadFile() per caricare l'assieme risultante.
  3. È ora possibile utilizzare la riflessione su get types dal gruppo e interrogate.

EDIT: In alternativa Csc.exe, si potrebbe usare CodeDOM - c'è un example che contiene tutto ciò che serve.

+0

Ho fatto una domanda simile qualche tempo fa su come ottenere valori parametar usati con il metodo usando il reflection ma purtroppo non c'erano risposte utili. È possibile? Perché quello sarebbe il modo di andare invece di espressioni regolari. – formatc

+0

@ user1010609 Non vedo come sia correlato a questa domanda - ma posta il link e posso dare un'occhiata a questo. –

+0

Non è rilevante, ma diciamo che voleva fare qualcosa di simile a 'Console.WriteLine (_name);', c'è modo di ottenere ciò che era il valore di '_name'? E se fosse hardcoded come 'Console.WriteLine (" John ");'? Perché la regex può farlo con facilità, ma rende le cose molto più complicate, voleva solo indirizzarlo verso la giusta direzione. – formatc

0

Un linguaggio come C# accetta troppe variazioni nella sintassi delle istruzioni da analizzare solo con le espressioni regolari. Oltre alle espressioni regolari, è necessario un parser di grammatica contestuale.

Vorrei dare una prova a Roslyn: È un compilatore C# i cui interni sono accessibili dal codice. Chiedi a Roslyn di analizzare il codice e interrogarlo su qualunque informazione tu abbia bisogno.

0

Suggerisco di guardare lo spazio dei nomi Microsoft.VisualStudio.CSharp.Services.Language e altre funzionalità di Visual Studio Extensibility. Ciò eliminerebbe la necessità di compilare.