【问题标题】:Matching a string in Lex that contains at least one upper and lower case letter,匹配 Lex 中至少包含一个大写和小写字母的字符串,
【发布时间】:2013-04-15 16:55:00
【问题描述】:

我正在尝试匹配一个由 4 到 8 个混合大小写字母组成的字符串,其中至少包含一个大写字母和一个小写字母。我试过 [a-zA-z]{4,8} 但它匹配像 abba 和 CREEEDD 这样的字符串,它们只包含小写或大写字母。这是可以在 Lex 中完成的,还是我需要以不同的方式完成?

【问题讨论】:

  • 由 4 到 8 个小写字母组成的字符串 你的意思是由 4 到 8 个混合大小写字母组成的字符串?

标签: c regex lex


【解决方案1】:

这需要正则表达式中的& (and) 操作,那么下面的就可以了:

((([a-zA-Z]*([a-z][a-zA-Z]*[A-Z])|([A-Z][a-zA-Z]*[a-z]))[a-zA-Z]*)&([a-zA-Z]{4,8})

但该操作不存在。当然,你可以在混合大小写中列举小写或大写位置的所有可能性,但这将是一个巨大的表达式。

过滤所有 4 到 8 个字符的字符串以不同方式检查是否存在小写和大写是否可行?也许您可以将第二个正则表达式应用于前者的结果。

附带说明:& 操作在理论上没有反对意见,因为确定性有限自动机在交集下是封闭的,尽管状态数量可能会爆炸。可能需要对非确定性有限自动机的常用解释器进行重大修改。

哦,如果有人觉得有挑战要有所作为,那么也不要忘记补语。

【讨论】:

  • 是否有可能创建一个匹配 [a-zA-Z]{4,8} 的规则并将匹配的字符串发送到一个函数,以确定它是否每个都有一个?我刚开始学习 Lex,所以我不知道。
  • 如果您在lex 工作,那么我肯定会检查规则操作中是否出现大小写,如果没有,则使用REJECT 去下一个最佳模式。 lex 中的链接规则(不幸的是)是不可能的。
【解决方案2】:

您需要一个包含零个或多个混合大小写字母的字符串,后跟一个大写字母、零个或多个混合大小写字母、一个小写字母和零个或多个混合大小写字母,或与小写类似的模式在大写之前。

但是,这很混乱。所以,我们可以尝试简化。第一个字符可能是大写的,所以我们需要它后跟零个或多个混合大小写字母,一个小写字母,以及零个或多个混合大小写字母。或者第一个字符可能是小写的,所以我们需要它后跟零个或多个混合大小写字母,一个大写字母,再有零个或多个混合大小写字母。

[a-z][a-zA-Z]*[A-Z][a-zA-Z]*|[A-Z][a-zA-Z]*[a-z][a-zA-Z]*

剩余的问题是将总长度限制在 4-8 个字符的范围内(请注意,如今只有 8 个字母字符对于密码来说是可悲的;允许标点符号和数字以及超过 8 个字符)。识别模式后,我将在操作中实现长度验证。

或者,可能更简单,使用您现有的规则:

[a-zA-Z]{4,8}

并在操作中应用混合大小写验证:

if (islower(yytext[0]) && strpbrk(yytext, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 0)
    ...reject...
else if (isupper(yytext[0]) && strpbrk(yytext, "abcdefghijklmnopqrstuvwxyz") == 0)
    ...reject...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    相关资源
    最近更新 更多