python - Matcha enradiga JavaScript-kommentarer (//) med re


Jag skulle vilja filtrera bort (främst enradiga) kommentarer från (främst giltig) JavaScript med Pythons re-modul. Till exempel:

// this is a comment
var x = 2 // and this is a comment too
var url = "http://www.google.com/" // and "this" too
url += 'but // this is not a comment' // however this one is
url += 'this "is not a comment' + " and ' neither is this " // only this

Jag har nu försökt med detta i mer än en halvtimme utan någon framgång. Kan någon vänligen hjälpa mig?

REDIGERA 1:

foo = 'http://stackoverflow.com/' // these // are // comments // too //

REDIGERA 2:

bar = 'http://no.comments.com/'

Svar #1

Mina regex-färdigheter hade blivit lite rostiga, så jag har använt din fråga för att friska upp det jag minns. Det blev en ganska stor regex mest för att jag också ville filtrera flerradiga kommentarer.

import re

reexpr = r"""
    (                           # Capture code
        "(?:\\.|[^"\\])*"       # String literal
        |
        '(?:\\.|[^'\\])*'       # String literal
        |
        (?:[^/\n"']|/[^/*\n"'])+ # Any code besides newlines or string literals
        |
        \n                      # Newline
    )|
    (/\*  (?:[^*]|\*[^/])*   \*/)        # Multi-line comment
    |
    (?://(.*)$)                 # Comment
    $"""
rx = re.compile(reexpr, re.VERBOSE + re.MULTILINE)

Denna regex matchar med tre olika undergrupper. En för kod och två för kommentarers innehåll. Nedan är ett exempel på hur man extraherar dessa.

code = r"""// this is a comment
var x = 2 * 4 // and this is a comment too
var url = "http://www.google.com/" // and "this" too
url += 'but // this is not a comment' // however this one is
url += 'this "is not a comment' + " and ' neither is this " // only this

bar = 'http://no.comments.com/' // these // are // comments
bar = 'text // string \' no // more //\\' // comments
bar = 'http://no.comments.com/'
bar = /var/ // comment

/* comment 1 */
bar = open() /* comment 2 */
bar = open() /* comment 2b */// another comment
bar = open( /* comment 3 */ file) // another comment 
"""

parts = rx.findall(code)
print '*' * 80, '\nCode:\n\n', '\n'.join([x[0] for x in parts if x[0].strip()])
print '*' * 80, '\nMulti line comments:\n\n', '\n'.join([x[1] for x in parts if x[1].strip()])
print '*' * 80, '\nOne line comments:\n\n', '\n'.join([x[2] for x in parts if x[2].strip()])

Svar #2

Det kan vara lättare att analysera om du hade tydliga semikolon.

I vilket fall fungerar detta:

import re

rx = re.compile(r'.*(//(.*))$')

lines = ["// this is a comment", 
    "var x = 2 // and this is a comment too",
    """var url = "http://www.google.com/" // and "this" too""",
    """url += 'but // this is not a comment' // however this one is""",
    """url += 'this "is not a comment' + " and ' neither is this " // only this""",]

for line in lines: 
    print rx.match(line).groups()

Utdata från ovanstående:

('// this is a comment', ' this is a comment')
('// and this is a comment too', ' and this is a comment too')
('// and "this" too', ' and "this" too')
('// however this one is', ' however this one is')
('// only this', ' only this')

Jag är inte säker på vad du gör med JavaScript efter att ha tagit bort kommentarerna, men JSMin kan hjälpa. Den tar ändå bort kommentarer tillräckligt bra, och det finns en implementation i Python.