【问题标题】:What's the regular expression for an alphabet without the first occurrence of a letter?没有第一次出现字母的字母表的正则表达式是什么?
【发布时间】:2021-01-03 15:06:49
【问题描述】:

我正在尝试使用 FLEX 来识别我需要的一些正则表达式。 我正在寻找的是给定一组字符,比如[A-Z],我想要一个可以匹配第一个字母的正则表达式,无论它是什么,然后是第二个字母,除了第一个之外,它可以是[A-Z] 中的任何内容信。

例如,如果我给你AB,你匹配它,但如果我给你AA,你不匹配。所以我有点想找一个像这样的正则表达式 [A-Z][A-Z^除了第一组中挑选的东西]

如何实现更多的字母出现?假设我想匹配 3 个字母,而每个新字母都不是以前的字母。例如ABC,但不是AAB

谢谢!

【问题讨论】:

    标签: regex compiler-construction flex-lexer


    【解决方案1】:

    (数学)正则表达式没有上下文。在 (f)lex 中——正则表达式实际上是正则表达式,与大多数正则表达式库不同——没有反向引用之类的东西,无论是正的还是负的。

    因此,使用 flex 模式实现目标的唯一方法是列举可能性,这对于两个字母来说是乏味的,而对于更多字母来说是不切实际的。两个字母的大小写类似于(缩写);

    A[B-Z]|B[AC-Z]|C[ABD-Z]|D[A-CE-Z]|…|Z[A-Y]
    

    逆向表达式也有 26 种情况,但更容易输入(和阅读)。您可以使用 (f)lex 的 first-longest-match 规则来使用它:

    AA|BB|CC|DD|…|ZZ    { /* Two identical letters */ }
    [[:upper:]]{2}  { /* This is the match */ }
    

    可能,这些都不是最好的解决方案。但是,如果不了解更多细节,我认为我无法提供更好的建议。关键是要知道如果字母匹配,您想采取什么行动,而您没有指定。以及其他模式是什么。 (回想一下,词法扫描器旨在将输入划分为标记,尽管一旦识别出标记,您可以随意忽略它。)

    Flex 确实带有许多有用的功能,可用于更灵活的令牌处理,包括yyless(重新扫描部分或全部令牌)、yymore(将匹配项与下一个令牌组合) , 和unput(在输入流中插入一个字符)。还有REJECT,但你应该先尝试其他解决方案。详情请见the flex manual chapter on actions

    所以最简单的解决方案可能是匹配任意两个大写字母,然后在操作中检查它们是否相同。

    【讨论】:

    • 只是为了给你更多的背景信息。问题是我有一个来自 [A-F] 的集合,我需要匹配几何形状的输入。例如,我需要匹配“点 A”而不是“点 AB”,然后我需要匹配线“CB”而不是线“AA”,依此类推,三角形到八边形。所以基本上对于每个规则,我需要匹配具有每个形状的确切字母长度的输入,并且以后没有第二次出现相同的字符。所以是的,我要做的是匹配具有确切数量的输入字母,然后比较每个字母不是之前的任何一个。
    • @HeyYoubooo:如果我们有一封重复的信,你想怎么办?再一次,词法扫描器的目标是将输入拆分为一系列标记。由于每个输入都是可能的,因此扫描仪必须处理每个输入。它将如何处理AA?如果它只需要产生错误,您可以在标记化后检查重复的字母。模式 9nly 需要区分它是否改变了将输入拆分为标记的方式。另外:应通过编辑问题进行澄清。不是每个人都会读 cmets。
    • 好的,会这样做。你能给我一个链接来检查标记化后的字母重复吗?您谈到了 lex 使用的一些函数。我对此有点陌生,因此不太了解。我会做的是,如果我找到正确的输入,然后我会使用一些 c 来检查每一个,然后输出一条消息,如果以后没有相同的给出。
    • @HeyYoubooo:我确实提供了 flex 操作的链接,但我仍然不知道您要做什么。检查字符串中的重复是一个常见的 C 练习 :-) 在有两个字符的情况下,这很简单:if (yytext[0] == yytext[1]) { /* the token has two identical characters */ }。对于较长的字符串,您可以在 SO 中搜索想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 2020-10-16
    • 2020-03-05
    • 2014-08-20
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多