捕获包含 -- 但不以破折号结尾 -- 的名称

Capture names containing --but not ending-- in dashes

我正在尝试捕获名称(不以数字开头)其中可能包含破折号,例如hello-world .我的问题是我也有与它冲突的单个破折号和符号的规则:

[A-Za-z][A-Za-z0-9-]+     { /* capture "hello-world" */ }
"-"                       { return '-'; }
">"                       { return '>'; }

当词法分析器读取 hello-world-> 时,先前的规则产生 hello-world->,而我期望 hello-world->要单独捕获。为了解决它,我这样修复它:

[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+     { /* ensure final dash is never included at the end */ }

有效,除了单字母单词,所以最后我实现了这个:

[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+     { /* ensure final dash is never included at the end */ }
[A-Za-z][A-Za-z0-9]*                  { /* capture possible single letter words */ }

问题:有没有更优雅的方式来做?

[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+
[A-Za-z][A-Za-z0-9]*

请注意,正如您所说,第一条规则已经涵盖了所有非单个字母的内容。所以第二条规则只需要匹配单个字母,可以缩短为 [A-Za-z]:

[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+
[A-Za-z]

现在第二条规则只是第一条的前缀,所以我们可以通过将第一个字母后面的部分设为可选来将其合并为一条规则:

[A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9]+)?

最后一位的+是不需要的,因为除了最后一个字符之外的所有字符都可以被中间部分匹配,所以最简单的版本是:

[A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?