0

我只能找到负面的回顾,比如(?<!\\)
但这不会在 c++ 和 flex 中编译。似乎 regex.h 和 flex 都支持这个?

我正在尝试实现一个外壳,如果前面有反斜杠,它必须将特殊字符 , 视为普通参数字符串>。换句话说,只有在前面没有 0 或偶数个 '\' 的情况下才将特殊字符视为特殊字符<|

所以echo \\>aecho abc>a应该直接输出到a
echo \>a应该打印>a

我应该使用什么正则表达式?
我正在使用 flex 和 yacc 来解析输入。

4

2 回答 2

1

在 Flex 规则文件中,您将\\用于匹配单个反斜杠 '\' 字符。这是因为\在 Flex 中用作转义字符。

    BACKSLASH           \\
    LITERAL_BACKSLASH   \\\\
    LITERAL_LESSTHAN    \\\\<
    LITERAL_GREATERTHAN \\\\>
    LITERAL_VERTICALBAR \\\\|

如果我正确地跟随你,在你的情况下,你希望 "\>" 被视为文字'>',但 "\\>" 被视为文字'\',然后是特殊重定向。您不需要负面的看法或任何特别的东西来完成此操作,因为您可以构建一个既接受常规参数字符又接受特殊字符的文字版本的规则。

出于讨论的目的,我们假设您的自变量/参数可以包含除“ ”、“\t”和特殊形式的“>”、“<”、“|”之外的任何字符。论点的规则将类似于:

    ARGUMENT ([^ \t\\><|]|\\\\|\\>|\\<|\\\|)+

在哪里:

[^ \t\\><|]匹配除 ' '、'\t' 之外的任何单个字符,并且您的特殊字符
\\\\匹配 "\" 的任何实例(即文字反斜杠)
\\>匹配 ">" 的任何实例(即文字大于)
\\<匹配 "\ 的任何实例<"(即文字小于)
\\\|匹配“\|”的任何实例 (即文字垂直条/管道)

实际上......您可能可以将该规则缩短为:

    ARGUMENT ([^ \t\\><|]|\\[^ \t\r\n])+

在哪里:

[^ \t\\><|]匹配除 ' '、'\t' 之外的任何单个字符,并且您的特殊字符
\\[^ \t\r\n]匹配输入中除空格以外的任何以 '\' 开头的字符(它将处理所有特殊字符并允许所有其他字符的文字形式)

如果你想在你的参数/参数中允许文字空格,那么你可以进一步缩短规则,但要小心使用\\.规则交替的后半部分,因为它可能匹配也可能不匹配“\n”(即吃掉你的尾随命令终止符!)。

希望有帮助!

于 2013-03-28T15:06:12.637 回答
0

You cannot easily extract single escaped characters from a command-line, since you will not know the context of the character. In the simplest case, consider the following:

 LessThan:\<
 BackslashFrom:\\<

In the first one, < is an escaped character; in the second one, it is not. If your language includes quotes (as most shells do), things become even more complicated. It's a lot better to parse the string left to right, one entity at a time. (I'd use flex myself, because I've stopped wasting my time writing and testing lexers, but you might have some pedagogical reason to do so.)

If you really need to find a special character which shouldn't be special, just search for it (in C++98, where you don't have raw literals, you'll have to escape all of the backslashes):

 regex: (\\\\)*\\[<>|]
     (An even number -- possibly 0 -- of \, then a \ and a <, > or |) 
 as a C string => "(\\\\\\\\)*\\\\[<>|]"
于 2013-03-06T18:53:26.470 回答