2009-09-14 17 views
6

Ich brauche Hilfe zu entsprechen versuchen, eine C übereinstimmen Include-Datei mit vollständigen Pfad wie folgt:Regulärer Ausdruck C# include Datei

#include <stdio.h> -> stdio.h 
#include "monkey/chicken.h" -> monkey/chicken.h 

Bisher habe ich (von einem anderen Ausdruck angepasst I gefunden):

Aber ich bin irgendwie an diesem Punkt fest - es passt nicht im zweiten Fall, und ich bin mir nicht sicher, wie das Ergebnis des Spiels, z. B. der Dateipfad zurück zu regcomp ().

BTW Ich habe regexplib.com angeschaut, kann aber nichts passendes finden.

Edit: Ja, ich bin ein total regexp Neuling, mit POSIX regex mit regmatch_t und Freunde ...

+0

Beachten Sie, dass es Räume zwischen den ‚#‘ sein kann und ‚umfassen‘. Beachten Sie auch, dass es ein drittes Formular gibt: # MACRONAME einschließen. MACRONAME muss entweder auf oder "etwas" erweitert werden. –

+0

Der "mittlere" Begriff mit seiner komplexen Zeichenklasse schließt Ihren zweiten Fall aus, indem er sagt "was in der Mitte nicht enthalten darf /". –

Antwort

5

Hier ist, was ich schrieb:

#include ((<[^>]+>)|("[^"]+")) 

sitzt das Ganze?

+0

Ja, schön und einfach. Ich werde wahrscheinlich optimieren, um mit Räumen robuster zu sein. Vielen Dank! – Justicle

+0

Suggest '(<[^>] +>)', um die und ähnliche für den anderen Begriff besser zu identifizieren. Sonst '#include // a> b' bekommt die falsche Information. Können Sie auch nicht erfassbare Klammern verwenden? Das hängt von der Regex-Bibliothek ab. –

+0

@ Jonathan natürlich könnte ich nicht-einfangende Klammern verwenden ... Was ist das? BTW, ich habe die Regex bearbeitet, ty =) –

2

Sie diese Regex versuchen:

(^\s*\#\s*include\s*<([^<>]+)>)|(^\s*\#\s*include\s*"([^"]+)") 

Ich ziehe es separate Regex haben für
#include <>
und
#include ""

4

Dies würde eine bessere resu geben lts:

Sie möchten dann die erste Erfassungsgruppe betrachten, wenn Sie eine Übereinstimmung erhalten.

Sie sagen nicht, welche Sprache Sie verwenden, der Faktor, den Sie regcomp() erwähnen, führt zu der Annahme, dass Sie die POSIX-Regex-Bibliothek in C verwenden. Wenn das richtig ist, möchten Sie die regexec-Funktion verwenden und benutze die nmatch- und pmatch-Parameter, um die erste Erfassungsgruppe zu erhalten.

+0

Yep POSIX Regex ist es, ich werde die Frage aktualisieren. – Justicle

+0

Theoretisch könnte man '#include ' oder '#include" name> this "' haben - einmal vor langer Zeit könnte die zweite in C für PRIMOS erschienen sein. In der Praxis ist beides nicht wahrscheinlich. –

+0

Jonathan: Ja, mir ist aufgefallen, dass dies nicht streng auf dem Standard basiert, aber ich dachte, dass Dateinamen, die entweder doppelte Anführungszeichen oder Größer als Zeichen enthalten, selten in der Wildnis (und C Source/Header-Dateien) scheinen in das "weniger komische Mist" Ende des Dateibenennungsspektrums zu fallen. –

1

Nicht besonders gut getestet, aber es entspricht Ihre zwei Fälle:

^\s*#include\s+(<([^"'<>|\b]+)>|"([^"'<>|\b]+)") 

Das einzige Problem ist, dass aufgrund des < und> Ding, das Ergebnis in Capture-Gruppe 2 oder 3 sein könnte, so sollten Sie überprüfe, ob 2 leer ist, dann benutze 3 ... Der Vorteil gegenüber einigen der anderen Antworten ist, dass es nicht wie folgt mit etw übereinstimmt: #include "bad.h> oder diese: #include < schlecht < <h>

Und hier ist ein Beispiel, wie man verwendet (wrap) regcomp & Freunde:

static bool regexMatch(const std::string& sRegEx, const std::string& sSubject, std::vector<std::string> *vCaptureGroups) 
{ 
    regex_t re; 
    int flags = REG_EXTENDED | REG_ICASE; 
    int status; 

    if(!vCaptureGroups) flags |= REG_NOSUB; 

    if(regcomp(&re, sRegEx.c_str(), flags) != 0) 
    { 
    return false; 
    } 

    if(vCaptureGroups) 
    { 
    int mlen = re.re_nsub + 1; 
    regmatch_t *rawMatches = new regmatch_t[mlen]; 

    status = regexec(&re, sSubject.c_str(), mlen, rawMatches, 0); 

    vCaptureGroups->clear(); 
    vCaptureGroups->reserve(mlen); 

    if(status == 0) 
    { 
    for(size_t i = 0; i < mlen; i++) 
    { 
    vCaptureGroups->push_back(sSubject.substr(rawMatches[i].rm_so, rawMatches[i].rm_eo - rawMatches[i].rm_so - 1)); 
    } 
    } 

    delete[] rawMatches; 
    } 
    else 
    { 
    status = regexec(&re, sSubject.c_str(), 0, NULL, 0); 
    } 

    regfree(&re); 

    return (status == 0); 
} 
+0

Hey! Ich passe nicht an '#include" bad.h> '! :( –

+0

a) Entschuldigung, habe deine Antwort nicht gesehen. b) Dein passt zB #include c) Auch nur notiert meins wird auch ' file.h '. Oh, tut mir leid. "Stupid PHP. Also eine gute Idee wäre, Clement's für die allgemeine Idee und meine für die Validierung zu kombinieren. – KiNgMaR

+0

Haha danke ich muss nicht nur simple alberne Includes zusammenbringen. – Justicle

2

WENN Sie genauere Lösung wollen, die auch Kommentare erlaubt, bevor die Datei wie zum Beispiel umfassen,

/* ops, a comment */ /* oh, another comment */ #include "new_header1.h" /* let's try another with an #include "old_header.h" */ 

ist:

^(?:\s*|\s*\/\*.*?\*\/)\s*#include\s*(?:(?:<)(?<PATH>.*?)(?:>)|(?:")(?<PATH>.*?)(?:")) 
0

Dies funktioniert für mich:

'\#include\s*(<([^"<>|\b]+)>|"([^"<>|\b]+)")'