如何编写允许不重复下划线的正则表达式

How to write a regular expression that allows non-repeating underscores

我正在做一项使用 Flex 创建词法分析器的家庭作业。我必须满足的最后一个要求是:

The definition for the identifiers should be modified so that underscores can be included, however, consecutive underscores, leading and trailing underscores should not be permitted.

给定的正则表达式是 [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]+)* 部分,它允许单个下划线后跟至少一个字母数字字符,整个字符零次或多次,以仅保留下划线可选。

我对 flex 不熟悉,现在你就得考虑其他方面了。

在你的 [A-Za-z]([A-Za-z0-9][_]?[A-Za-z0-9])* 中,第一个 [A-Za-z0-9] can/must 被省略(考虑例如单字母标识符),导致 [A-Za-z]([_]?[A-Za-z0-9])*。这似乎正是所要求的,并且似乎是研究在正则表达式中重复组合可选元素的效果的一个很好的练习。

通过这个,让我们从这个开始:

^    [A-Z][A-Z\d_]+    $

现在,我们要说的是,我们需要确保字符串中不出现两个连续的下划线。通常我们要做的是将其包含在负面前瞻中,如下所示:

(?:(?!__).)+

当我们将它插入到我们的表达式中时,我们最终得到这样的东西,它允许任何字符,只要它不是换行符或双下划线:

^    [A-Z]    (?:(?!__).)+    $

所以,我们可以把点替换成我们一开始定义的字符class:

^    [A-Z]    (?:(?!__)[A-Z\d_])+    $

Here is a demo

编辑:刚意识到最后也不能有下划线。使用前瞻,您可以链接它们。

^[A-Z]    (?:    (?!__)    (?!_$)    [A-Z\d_]    )+$

在这里,我为双下划线添加了一个否定前瞻,为末尾的下划线添加了另一个。

Here is a demo

要想做你想做的事,你必须牢记以下几点:

  • 以字母数字值开头 (^)
  • 以字母数字值结尾 ($)
  • 可选下划线(_?
  • 可能有多个下划线,后面始终跟有字母数字 ()*

示例

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

在这里测试:https://regex101.com/r/RORy6P/5

如果需要,您可以离开锚点。