Regex 可选的带文件结尾的JFlex前瞻

Regex 可选的带文件结尾的JFlex前瞻,regex,fitnesse,jflex,Regex,Fitnesse,Jflex,我正在尝试使用JFlex为Fitnesse编写一个lexer,但在使用WikiWords时遇到了问题(http://fitnesse.org/FitNesse.UserGuide.WikiWord) 我复制了链接的正则表达式,并使用以下正则表达式作为令牌: . # Regular character [A-Z]([a-z0-9]+[A-Z][a-z0-9]*)+ # WikiWord 不过,我在正确分析这不是WikiWord时遇到了问

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

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

.                               # Regular character
[A-Z]([a-z0-9]+[A-Z][a-z0-9]*)+ # WikiWord
不过,我在正确分析
这不是WikiWord
时遇到了问题。它一行有两个大写字母,因此不应将其视为常规单词。因此,我需要添加一个前瞻,以检查下一个字符是字母还是数字。类似于
[A-Z]([A-z0-9]+[A-Z][A-z0-9]*)+/[^A-Za-z0-9]

这对于词法分析
很好,这不是Wikiword
,但它通常会破坏对WikiWords的词法分析。在对WikiWord进行词法分析时,前瞻没有额外的字符,因此不匹配

我想我需要一个可选的前瞻。如果在这之后有一个字符,那么它最好不是这些字符之一。但是如果输入中没有其他字符,让我们进行匹配

文档让我相信这是不可能的,但我希望这只是因为我缺少正则表达式fu。从文档中:

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

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


环顾四周,这里似乎不需要什么东西

据我所知,您正在寻找以大写字母开头但可以包含数字的驼峰大小写单词,其中一个数字作为小写字母计算,每个驼峰大小写只能是一个大写字母。如果这是正确的,这个regexp应该适合您:

\b((?:[A-Z][a-z\d]+){2,})\b
(?:
部分使括号不可捕获

[A-Z][A-Z\d]+
确保恰好有一个大写字符后跟至少一个小写字符


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

您应该使用正确的单词边界(
\b
)或者您的正则表达式将在两个连续的WikiWords上以一个空格分隔时失败。@TimPietzcker,谢谢。您对单个空格的看法是正确的,但单词边界并不完全相同。它们也匹配标点符号,但不清楚所需的边界是什么。如果不允许标点符号作为边界,则后面需要查找呃…@d_不可避免地感谢您的快速响应,并对延迟表示抱歉。不幸的是,JFlex似乎不支持
(?:
)而只支持
\b([A-Z][A-Z\d]+([A-Z][A-Z\d]+)\b
,JFlex声称由于某种原因它无法匹配
WikiWord
的输入。(@GeorgeShakhnazaryan
(?:
无论如何都是可选的,如果它不支持它,并且您需要捕获匹配的部分,那么您只需要相应地调整偏移量。我可以想象它不匹配的唯一方法是它位于字符串开始或结束处,并且
\b
与我所知道的所有regexp引擎都不一样。请尝试r分别用
(\b|^)
(\b|$)
替换它。否则,请将您匹配它的完整字符串发送给我。@d|您提供的原始和修改的正则表达式是有意义的。不幸的是,JFlex中的正则表达式支持似乎有限。在处理
(\b|^)时([A-Z][A-Z\d]+([A-Z][A-Z++)(\d])(\b|$)
,JFlex给出了一个语法错误。它似乎只接受
^
$
作为第一个和最后一个字符。而
$
只匹配一行的结尾,而不是输入的结尾。好的一面是,我想我找到了解决问题的另一个方法。以前,我将
作为非wikiword文本进行词法分析。相反,我可以只使用lex
[A-Za-z0-9]
作为非wikiwords。JFlex将使用与最长输入匹配的正则表达式。谢谢,George