【问题标题】:Optional JFlex lookahead with End of File带有文件结尾的可选 JFlex 前瞻
【发布时间】:2012-07-30 04:48:34
【问题描述】:

我正在尝试使用 JFlex 为 Fitnesse 编写词法分析器,但在使用 WikiWords 时遇到了问题 (http://fitnesse.org/FitNesse.UserGuide.WikiWord)

我复制了链接的正则表达式,并使用以下正则表达式作为标记:

.                               # Regular character
[A-Z]([a-z0-9]+[A-Z][a-z0-9]*)+ # WikiWord

不过,我无法正确地对 ThisIsNotAWikiWord 进行词法分析。它连续有 2 个大写字母,因此不应将其视为常规单词。所以我需要添加一个前瞻来检查下一个字符是字母还是数字。类似于[A-Z]([a-z0-9]+[A-Z][a-z0-9]*)+ / [^A-Za-z0-9]

这对于 ThisIsNotAWikiWord 的词法分析很有效,但它通常会破坏 WikiWords 的词法分析。在对WikiWord 进行词法分析时,前瞻没有多余的字符,因此不匹配。

我想我想要一个可选的前瞻。如果在此之后有一个字符,那么最好不要成为其中之一。但如果输入中没有其他字符,我们就匹配吧。

文档让我相信这是不可能的,但我希望这只是我缺乏 regex-fu。来自文档:

在词法规则中,正则表达式 r 可以后跟前瞻表达式。前瞻表达式是“$”(行尾运算符)或“/”后跟任意正则表达式。在这两种情况下,前瞻都不会被消耗,也不会包含在匹配的文本区域中,但在确定哪个规则具有最长匹配时会考虑它(另请参阅 4.3.3 如何匹配输入)。

在“$”的情况下,r 只匹配输入中一行的末尾。行尾由正则表达式 \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085 表示。所以 a$ 等价于 / \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085。这与 [5] 中描述的情况有点不同:因为在JFlex $ 是一个真正的尾随上下文,文件结尾不计为行尾。

【问题讨论】:

    标签: regex fitnesse jflex


    【解决方案1】:

    这里似乎不需要环顾四周。

    据我了解,您正在寻找以大写字母开头但可以包含数字的驼峰式单词,其中数字算作小写字母,每个驼峰形必须是一个大写字母只写信。如果这是正确的,这个正则表达式应该适合你:

    \b((?:[A-Z][a-z\d]+){2,})\b
    

    (?: 部分使括号不被捕获。

    [A-Z][a-z\d]+ 确保正好一个大写字符后跟至少一个小写字符。

    {2,} 强制模式至少重复两次,以便至少产生一个驼峰。

    【讨论】:

    • 您应该使用正确的单词边界 (\b) 否则您的正则表达式将在两个由一个空格分隔的连续 WikiWords 上失败。
    • @TimPietzcker 谢谢。您对单个空格是正确的,但是单词边界并不完全相同。它们也匹配标点符号,但不清楚所需的边界是什么。如果不允许标点符号作为边界,那么毕竟需要环顾四周......
    • @d_inevitable 感谢您的快速回复,并对延误表示歉意。不幸的是,JFlex 似乎不支持(?: 只有\b([A-Z][a-z\d]+([A-Z][a-z\d]+)+)\b,JFlex 声称由于某种原因它无法匹配WikiWord 的输入。 :(
    • @GeorgeShakhnazaryan (?: 无论如何都是可选的,如果它不支持它并且您需要捕获匹配的部分,那么您只需要相应地调整偏移量。我可以想象它与WikiWord 不匹配的唯一方法是,如果它位于字符串开头或结尾并且\b 与我所知道的所有正则表达式引擎不同。尝试分别用(\b|^)(\b|$) 替换它。否则,请将您与之匹配的完整字符串发送给我。
    • @d_inevitable 您提供的原始和修改的正则表达式是有意义的。不幸的是,JFlex 中的正则表达式支持似乎是有限的。在处理(\b|^)([A-Z][a-z\d]+([A-Z][a-z\d]+)+)(\b|$) 时,JFlex 给出了一个语法错误。它似乎只接受 ^$ 作为第一个和最后一个字符。而$ 只匹配一行的结尾,而不是输入的结尾。从好的方面来说,我认为我找到了解决问题的另一种方法。之前,我将. 用作非维基词文本。相反,我可以将 [A-Za-z0-9] 作为非维基词。 JFlex 将使用匹配最长输入的正则表达式。谢谢,乔治
    猜你喜欢
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 2016-01-10
    • 2012-11-14
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多