Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Regex (match nested comments)

Îåêßíçóå áðü ôï ìÝëïò cap. Τελευταία δημοσίευση από το μέλος George J. Capnias στις 02-04-2005, 08:29. Υπάρχουν 7 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  01-04-2005, 11:35 1518

    Regex (match nested comments)

    Τα δεδομένα μου:
    Εχω τον κώδικα ενός τυχαίου SQL Script το οποίο περιέχει comments της μορφής  "/* bla bla */" και ενδεχομένως και nested τέτοια (multiline).

    Εχω ένα ωραίο UDF που τα αφαιρεί, το θέμα είναι οτι κάνει χρόνια. Εψαχνα λοιπόν να κάνω το ίδιο πράγμα με regular expressions.

    Μετά από μια μικρή έρευνα, κατέληξα στα εξής:

    RegexOptions.Multiline + RegexOptions.CultureInvariant + RegexOptions.ECMAScript
    Και το regular expression μου είναι το: /\*[\d\D]*?\*/

    Το θέμα είναι οτι αυτό δεν δουλεύει σωστά σε nested comments. Φυσικό, γιατί κάνει match στο start του εξωτερικού comment μέχρι το end του εσωτερικού.
    Θέλω λοιπόν κάτι που να κάνει match στα "/*anycharacters*/" ΜΟΝΟ όμως όταν το anycharacters δεν περιέχει τα strings "/*", "*/". Ετσι θα μπορούσα να αφαιρώ τα εσωτερικά comments πρώτα και μετά να κάνω match στα υπόλοιπα.

    Καμμία πρόταση; Επισκέφτηκα ήδη το www.regexlib.com αλλά καμμία τύχη με τα nested comments.


     


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  01-04-2005, 11:52 1519 σε απάντηση της 1518

    Re: Regex (match nested comments)

    Το απλό /\*.*\*/ με SingleLine (μόνο) κάνει match στο string
    adsf/*asd
    /*fads*/
    asd*/adf

    το
    /*asd
    /*fads*/
    asd*/


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  01-04-2005, 11:59 1520 σε απάντηση της 1519

    Re: Regex (match nested comments)

    Χμ, το είχα δοκιμάσει αυτό. Δεν έπαιζε σωστά. Και θέλω multiline.

    Οπως:

    some code here

    /*
    some outer comments

    /* some other inner comments
    some more inner comments
    */

    some more outer comments
    */

    some more code here

    Αυτό που θέλω να μείνει τελικά είναι τα:
    some code here
    some more code here

    Κανοντας match τα υπόλοιπα. Σκεφτόμουν να βρω ενα τρόπο να κάνω πρώτα match το:
    /* some other inner comments
    some more inner comments
    */
    να το αφαιρέσω και μετά να κάνω match το εξωτερικό.



    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  01-04-2005, 14:20 1523 σε απάντηση της 1520

    Re: Regex (match nested comments)

    Λοιπον τελικά έβαλα και λίγο (!) VB.NET μέσα. Αμα έχει κανείς όρεξη, ας το δει μήπως και κατι μου έχει ξεφύγει. Φαίνεται οτι δουλεύει.

    Βασικά είναι μια φόρμα με δύo textboxes, TextBox1 (source) TextBox2 (destination). Παίρνει το text του source, και το παρσάρει φτύνοντάς το στο destination. (Δοκιμή είναι, μην βαράτε για τα ονόματα) Smile

    Επίσης: ΠΩΣ μπορω να κάνω σωστό paste κώδικα σε αυτό τον editor? Μου έχει σπάσει τα νεύρα...αν κάνω μέσα από το VS βγαίνει το colorization, δεν βγαίνουν τα indents...αν κάνω paste σε notepad και μετά εδώ...οριστε το αποτέλεσμα....



        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.TextBox2.Text = RemoveCommentBlocks(TextBox1.Text)
        End Sub
        '/// <summary>
        '/// Removes "/*...*/" comment blocks (single-line and multi-line) from our string
        '/// taking care of possible nested comment blocks. Also calls RemoveInlineComments
        '/// which removes "--...." comments.
        '/// </summary>
        '/// <param name="strText">The string representing the code to remove the comments from</param>
        '/// <returns>String</returns>
        Private Function RemoveCommentBlocks(ByVal strText As String) As String
            'StringBuilder is created for speed. 
            'The stringbuilder takes the output of RemoveInlineComments which
            'removes all "--...." things.
            Dim objSB As New StringBuilder(RemoveInlineComments(strText))
            'Create a regular expression to match "/* ... */" patterns
            Dim objRegEx As _
                     New Regex("/\*[\d\D]*?\*/", _
                      RegexOptions.Multiline _
                    + RegexOptions.CultureInvariant _
                    + RegexOptions.ECMAScript)
            'Start parsing our code to find "/* ... */" patterns. 
            'We may also find "/*.../*...*/" patterns if we have nested comments
            'But we will take care of them using FindInner()
            Try
                'Go on as long as we find matches
                While (Not objSB.Equals(String.Empty)) AndAlso objRegEx.IsMatch(objSB.ToString)
                    'If we find a match check whether it is a "/*.../*...*/" pattern
                    'using FindInner
                    Dim strMatch As String = objRegEx.Match(objSB.ToString).ToString
                    objSB.Replace(FindInner(strMatch, objRegEx), "")
                End While
                'Spit the result 
                Return (objSB.ToString)
            Catch ex As Exception
                'Silly exception handling
                MsgBox(ex.Message)
            End Try
        End Function
        '/// <summary>
        '/// Removes inline "--..." comments
        '/// </summary>
        '/// <param name="strText">The string representing the code to remove the comments from</param>
        '/// <returns>String</returns>
        Private Function RemoveInlineComments(ByVal strText As String) As String
            'Create a StringBuilder for speed
            Dim objSB As New StringBuilder(strText)
            'Create a regular expression to match "--..." patterns
            Dim objRegEx As _
                New Regex("--.*$", _
                  RegexOptions.Multiline _
                + RegexOptions.CultureInvariant _
                + RegexOptions.ECMAScript)
            Try
                'Go on while we have a match
                While (Not objSB.Equals(String.Empty)) AndAlso objRegEx.IsMatch(objSB.ToString)
                    'Take care of the match
                    Dim strMatch As String = objRegEx.Match(objSB.ToString).ToString
                    objSB.Replace(strMatch, ControlChars.CrLf)
                End While
                'Spit result
                Return (objSB.ToString)
            Catch ex As Exception
                'Silly exception handling
                MsgBox(ex.Message)
            End Try
        End Function
        '/// <summary>
        '/// Finds inner blocks in strings following a "/*.../*...*/" pattern and locates the
        '/// innermost block
        '/// </summary>
        '/// <param name="strMatch">A string that comes from a regular expression match
        '/// which follows a "/*.../*...*/" pattern
        '/// </param>
        '/// <param name="objRegEx">The regular expression that searches for "/*...*/" patterns</param>
        '/// <returns>String</returns>
        Private Function FindInner(ByVal strMatch As String, ByVal objRegEx As Regex) As String
            'Get the position of the second "/*" we may have inside our string
            Dim intPos As Int32
            intPos = InStr(strMatch.Substring(3, Len(strMatch) - 5), "/*")
            If intPos > 1 Then
                'If we've got an "/*" inside our string, recursively call
                'our function in case we've got more than one levels of nested
                'comment blocks.
                Return FindInner(objRegEx.Match(strMatch.Substring(intPos, Len(strMatch) - intPos)).ToString, objRegEx)
            Else
                'We haven't got "/*"s inside our string anymore,
                'so return the resulting string. If we initially got a string which
                'does not contain an "/*", the function will just return the same string
                Return strMatch
            End If
        End Function
     



     

     


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  01-04-2005, 15:46 1527 σε απάντηση της 1523

    Re: Regex (match nested comments)

    Για σωστό paste κώδικα δοκίμασε το button VBButtonπου έχει πάνω από το box που γράφεις.
    There are 10 types of people in this world... Ones that understand binary and the ones that don't.
  •  01-04-2005, 16:01 1528 σε απάντηση της 1527

    Re: Regex (match nested comments)

    Ε, αυτό ήταν προφανές οτι θα το είχα ήδη δοκιμάσει Smile Αλλα το κακό είναι οτι το πρόβλημα παραμένει. Χμ...χρησιμοποιώ Maxthon και οχι IE. (Τη μηχανή του IE εχει βεβαια). Λες να φταιει κατι;....Χμ...θα δοκιμάσω πάλι με ΙΕ...δοκίμασα! Τα ιδια...:( :( :(


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  01-04-2005, 20:04 1535 σε απάντηση της 1528

    Re: Regex (match nested comments)

    Sorry. Δεν το είχα τσεκάρει. Embarrassed
    Το δοκίμασα και με IE και με Firefox και όντως δε παίζει σωστά. Στον IE παίζει το colorization όντως αλλά χάνει τα tabs ενώ στο FireFox δεν παίζουν ούτε τα χρώματα.
    There are 10 types of people in this world... Ones that understand binary and the ones that don't.
  •  02-04-2005, 08:29 1544 σε απάντηση της 1535

    Re: Regex (match nested comments)

    Αν ήταν αυτά τα σημαντικά προβλήματα του FreeTextBox δεν θα είχαμε λόγο ανυσηχίας... Wink

    Το κακό είναι ότι και στη νεότερη έκδοσή του που είναι στο CS 1.0 θα βρείτε περισσότερα περίεργα...

    George J.


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems