我正在做一个词法分析器作为大学类(class)的一部分。我们教授给我们的脑筋急转弯之一(对评分没有贡献的额外作业)是我们如何在字符串文字中实现注释。
我们的字符串文字以感叹号开始和结束。例如!this is a string literal!
我们的评论以三个句点开始和结束。例如...This is a comment...
从字符串文字中删除注释相对简单。只需通过 /!.*!/
匹配字符串文字并通过正则表达式删除评论。如果连续的逗号超过三个,但没有结尾的逗号,则抛出错误。
但是,我想更进一步。我想在字符串文字中实现感叹号的转义。不幸的是,我似乎无法同时使用注释和感叹号转义。
我想要创建的是可以包含注释和感叹号转义的字符串文字。这怎么可能?
例子:
!Normal string!
!String with escaped \! exclamation mark!
!String with a comment ... comment ...!
!String \! with both ... comments can have unescaped exclamation marks!!!... !
这是我当前的代码,不能忽略注释中的感叹号:def t_STRING_LITERAL(t):
r'![^!\\]*(?:\\.[^!\\]*)*!'
# remove the escape characters from the string
t.value = re.sub(r'\\!', "!", t.value)
# remove single line comments
t.value = re.sub(r'\.\.\.[^\r\n]*\.\.\.', "", t.value)
return t
最佳答案
也许这可能是另一种选择。
使用第一个否定字符类匹配 0+ 次除反斜杠、点或感叹号之外的任何字符。
然后,当您匹配第一个字符类不匹配的字符时,请使用替换来匹配:
为了防止灾难性的回溯,您可以在 Python 中使用正向前瞻和内部捕获组来模拟原子组。如果断言为真,则使用对
\1
的反向引用匹配。例如
(?<!\\)![^!\\.]*(?:(?:\.(?!\.\.)|(?=(\.{3}.*?\.{3}))\1|\\.)[^!\\.]*)*!
说明(?<!\\)!
比赛 !前面没有直接\
[^!\\.]*
匹配除 !
以外的任何字符 1+ 次\
或 .
(?:
非捕获组(?:\.(?!\.\.)
匹配一个不直接跟在 2 个点后面的点 |
或 (?=(\.{3}.*?\.{3}))\1
来自 ...
的组 1 中的断言和捕获到最近的 ...
|
或 \\.
匹配转义字符 )
关闭群 [^!\\.]*
匹配除 !
之外的任何字符 1+ 次\
或 .
)*!
关闭非捕获组并重复 0+ 次,然后匹配 !
Regex demo
关于python - 如何忽略字符串文字中的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64210788/