我只能找到负面的背后隐藏,例如(?<!\\)
但这不会在c ++和flex中编译。似乎regex.h和flex都支持这个吗?
我正在尝试实现一个shell,它必须将>
的{{1}},<
等特殊字符作为正常参数字符串处理,如果前面是反斜杠。换句话说,只将特殊字符作为特殊字符处理,如果不是前面的0或偶数“\”
因此|
或echo \\>a
应将输出定向到echo abc>a
但是a
应该打印echo \>a
我应该使用什么正则表达式?
我正在使用flex和yacc来解析输入。
答案 0 :(得分:1)
在Flex规则文件中,您使用\\
来匹配单个反斜杠'\'字符。这是因为\
在Flex中用作转义字符。
BACKSLASH \\
LITERAL_BACKSLASH \\\\
LITERAL_LESSTHAN \\\\<
LITERAL_GREATERTHAN \\\\>
LITERAL_VERTICALBAR \\\\|
如果我正确地关注您,在您的情况下,您需要“\&gt;”被视为文字'&gt;'但是“\\&gt;”被视为文字'\'后跟特殊重定向。你不需要负面的背后或任何特别特别的东西来完成这个,因为你可以建立一个规则,既接受你的常规参数字符,也接受你的特殊字符的文字版本。
出于讨论的目的,我们假设你的参数/参数可以包含任何字符,但是'','\ t'和'&gt;','&lt;','|'的特殊形式。参数的规则就是:
ARGUMENT ([^ \t\\><|]|\\\\|\\>|\\<|\\\|)+
其中:
[^ \t\\><|]
匹配任何单个字符,但是'','\ t'和您的特殊字符
\\\\
匹配“\”的任何实例(即字面反斜杠)
\\>
匹配“&gt;”的任何实例(即大于的字面数)
\\<
匹配“\&lt;”的任何实例(即文字少于)
\\\|
匹配“\ |”的任何实例(即文字垂直条/管)
实际上......您可以将该规则缩短为:
ARGUMENT ([^ \t\\><|]|\\[^ \t\r\n])+
其中:
[^ \t\\><|]
匹配任何单个字符,但是'','\ t'和您的特殊字符
\\[^ \t\r\n]
匹配输入中前面带有'\'的任何字符,除了空格(它将处理所有特殊字符并允许所有其他字符的文字形式)
如果你想在你的参数/参数中允许使用文字空格,那么你可以进一步缩短规则,但要小心使用\\.
进行规则交替的后半部分,因为它可能匹配也可能不匹配“ \ n“(即吃掉你的尾随命令终止符!)。
希望有所帮助!
答案 1 :(得分:0)
您无法从命令行轻松提取单个转义字符,因为您不会知道该字符的上下文。在最简单的情况下,请考虑以下事项:
LessThan:\<
BackslashFrom:\\<
在第一个中,<
是一个转义字符;在第二个,它不是。如果您的语言包含引号(就像大多数shell一样),事情会变得更加复杂。从左到右解析字符串要好得多,一次解析一个实体。 (我自己使用flex
,因为我已经不再浪费时间编写和测试词法分析器,但是你可能有一些教学理由这样做。)
如果你真的需要找一个不应该特殊的特殊字符,那就去搜索它(在C ++ 98中,你没有原始文字,你必须逃避所有的反斜杠) :
regex: (\\\\)*\\[<>|]
(An even number -- possibly 0 -- of \, then a \ and a <, > or |)
as a C string => "(\\\\\\\\)*\\\\[<>|]"