我正在做家庭作业,使用Flex来创建词法分析器。我必须满足的最后一项要求是:
应修改标识符的定义,以便可以包含下划线,但是,不应允许连续的下划线,前导和尾随下划线。
给定的正则表达式是[A-Za-z][A-Za-z0-9]*
。让它识别下划线很容易,我只是将它添加到像[A-Za-z][A-Za-z0-9_]*
这样的第二组。因此,正则表达式与带有前导下划线的任何字符串都不匹配。
在做尽职调查以确保我没有发布我不需要的东西时,我创建了这个似乎适用于[A-Za-z]([A-Za-z0-9][_]?[A-Za-z0-9])*
的正则表达式。这会在开头查找一个字母,然后是重复的图案或字母数字字符,可能的下划线和字母数字字符。虽然这有效,但我认为这不是预期的,并且希望能以更好的方式获得一些建议
我一直在测试使用以下字符串(由教师提供):
name_1
name__2
_name3
name4_
在你的[A-Za-z]([A-Za-z0-9][_]?[A-Za-z0-9])*
中,第一个[A-Za-z0-9]
可以/必须省略(考虑例如单个字母标识符),导致[A-Za-z]([_]?[A-Za-z0-9])*
。这似乎正是所要求的,并且似乎是一个很好的练习,可以研究在正则表达式中重复组合可选元素的效果。
要将正则表达式扩展为可选地一次只允许一个下划线夹在字符串中,您可以使用此正则表达式。
[A-Za-z][A-Za-z0-9]*(_[A-Za-z0-9]+)*
我刚刚添加了(_[A-Za-z0-9]+)*
部分,它将允许单个下划线,后跟至少一个字母数字字符整数零次或多次,只保留下划线可选。
现在你将不得不照顾其他方面,因为我不熟悉flex。
要做你想做的事,你必须记住一些事情:
^
)$
)_?
)()*
例:
^[A-Za-z]+(_?[A-Za-z0-9]+)*$
在这里测试:https://regex101.com/r/RORy6P/5
如果需要,您可以将锚固件放在一边。
走过这个,让我们从这开始:
^ [A-Z][A-Z\d_]+ $
现在,我们想说我们需要确保两个连续的下划线不出现在字符串中。通常我们要做的是将其包含在负向前瞻中,如下所示:
(?:(?!__).)+
当我们将它插入到我们的表达式中时,我们最终得到类似这样的东西,它允许任何字符,只要它不是换行符或双下划线:
^ [A-Z] (?:(?!__).)+ $
所以,我们可以用我们在开头定义的字符类替换点:
^ [A-Z] (?:(?!__)[A-Z\d_])+ $
编辑:刚才意识到你最后也不能有下划线。通过前瞻,您可以链接它们。
^[A-Z] (?: (?!__) (?!_$) [A-Z\d_] )+$
在这里,我为双下划线添加了一个负向前瞻,在末尾添加了另一个下划线。