"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

regex (javascript): find occurrence not in comments

wergor 31.03.2017 - 11:17 1874 5
Posts

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4030
ich suche eine möglichkeit, mittels regex in einer javascript file matches zu finden, die nicht innerhalb eines javascript zeilen- oder blockkommentars liegen. ein code snippet sähe z.b. so aus:
Code: JS
/*
 * use foo(number) to do the thing. you can also provide a second parameter 
 * foo(number, number) to use an alternate method.
 */
 
foo(3.141);
// foo(3.141, 2.718);        //skip this for now
in diesem fall soll nur foo(3.141); gematched werden. ich habe gestern schon einige zeit recherchiert und expressions gefunden die block- und zeilenkommentare matchen können, aber noch keine möglichkeit nicht innerhalb von kommentaren zu matchen. zumindest zeilenkommentare kann ich beim matchen ignorieren mit
Code: JS
/[\\r\\n](?!\\/).*foo\\(.*\\)/g
es dürfen auch mehrere regexs sein, die hintereinander ausgeführt werden.

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4030
niemand? :(

Hansmaulwurf

u wot m8?
Avatar
Registered: Apr 2005
Location: VBG
Posts: 5639
Zitat von wergor
ich habe gestern schon einige zeit recherchiert und expressions gefunden die block- und zeilenkommentare matchen können, aber noch keine möglichkeit nicht innerhalb von kommentaren zu matchen.
Blöde Frage, die andere Richtung ist keine Option?
Also etwa:
Du liest das File ein in eine variable. Aus der extrahierst die Kommentare via regex (zum matchen der Kommentare scheints ja genug zu geben). Die extrahierten Zeilen löscht du aus der ursprünglichen Variable und suchst dann? Ist etwas umständlich, und wenn runtime wichtig ist wohl nicht optimal, aber zumindest eine Lösung :p

Bzw. andere Idee wäre die expression die die Kommentare matched umzudrehen, so wie hier beschrieben : http://stackoverflow.com/questions/...atched-patterns


hth

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4030
wäre natürlich auch möglich. ich müsste nur herausfinden wie ich ganze textblöcke aus strings löschen kann... (vielleicht eh einfach mit String.replace()?)
ich habs nicht vergessen, bin nur gerade mit anderen dingen beschäftigt, ich weis noch nicht wann das thema wieder aktuell wird.

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25381
Mein Vorschlag wäre ebenfalls, die Kommentare zuerst zu entfernen und dann erst nach deinem Pattern zu matchen. Ich hatte dafür eine Weile eine Regular Expression, aber das Parsen innerhalb von Strings zu vermeiden, ist ziemlich aufwendig. Deshalb habe das mittlerweile per simplem Line-Parsing in PHP implementiert und verwende diesen Code heute noch in meinem Framework.

In $szContent muss das Textfile rein und in dieser Variable kommt es auch wieder raus. Es werden Strings mit Single- und Double-Quote unterstützt, sowie Single- und Multiline-Kommentare.

Code: PHP
$aLines = explode("\n",$szContent);

if (Util::countArray($aLines) > 0)
{
    $szRawContent = "";
    $bInComment	  = false;

    foreach ($aLines as $szLine)
    {
        $szLine = trim($szLine,"\r\t ");
        if (!$szLine)
            continue;

        $bInString	  = false;
        $szStringChar = null;

        $nChars = strlen($szLine);
        for ($i=0;$i < $nChars;$i++)
        {
            $szLastChar = $i > 0		 ? $szLine[$i-1] : null;
            $szNextChar = $i < $nChars-1 ? $szLine[$i+1] : null;

            if ($szLine[$i] == '/' &&
                $szNextChar	== '/' && !$bInString)
            // => single line comment
                break;

            if ($szLine[$i] == '/' &&
                $szNextChar == '*' && !$bInString)
            // => multi-line comment - open
            {
                $bInComment = true;

                $i++;
                continue;
            }

            if ($szLine[$i] == '*' &&
                $szNextChar == '/' && !$bInString)
            // => multi-line comment - close
            {
                $bInComment = false;

                $i++;
                continue;
            }

            if (($szLine[$i] == '"' || $szLine[$i] == "'") && !$bInComment)
            // => quoted string
            {
                if ($bInString)
                {
                    if ($szLine[$i] == $szStringChar && $szLastChar != "\\")
                    {
                        $bInString	  = false;
                        $szStringChar = null;
                    }
                }
                else
                {
                    $bInString	  = true;
                    $szStringChar = $szLine[$i];
                }
            }

            if (!$bInComment && ($bInString || ($szLine[$i] != ' ' && $szLine[$i] != "\t" && $szLine[$i] != "\r")))
                $szRawContent .= $szLine[$i];
        }

        $szRawContent .= "\n";
    }

    $szContent = $szRawContent;
}

Das kann man sicher recht schnell für Javascript umschreiben.

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4030
danke mat! sieht aus als wäre das mit vertretbarem aufwand auf js zu übersetzen.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz