... | perl -pe "s/([^$filespec]*)($filespec)/ ...
所以我有一个功能,如果是大多数事情,上面的构造工作正常$filespec
。但是,如果文件名中有破折号,我会收到一条Invalid [] range
消息。
我如何确保变量$filespec
扩展为不受此类解析错误影响的文件名?
... | perl -pe "s/([^$filespec]*)($filespec)/ ...
所以我有一个功能,如果是大多数事情,上面的构造工作正常$filespec
。但是,如果文件名中有破折号,我会收到一条Invalid [] range
消息。
我如何确保变量$filespec
扩展为不受此类解析错误影响的文件名?
关键假设——
$filespec
只是您要匹配的一组字符。它不是正则表达式。让我们用一些代码模拟这个问题
跑步给
当
$filespec
在您的正则表达式中将 扩展为m/[^z-a]/
. 在这个例子中z-a
是一个无效的字符范围。要修复你需要(至少)转义
-
in$filespec
。使用quotemeta
应该可以使问题消失,就像这样输出是
将其包含在您的管道命令的模拟中。首先是失败的命令版本
跑步给
这是固定版本
括号表达式中的破折号被视为范围,除非它用反斜杠1转义或者是表达式中的第一个或最后一个字符(或者,如果表达式被
^
后面的第一个字符^
或最后一个字符否定)。例如
[a-z]
a
匹配从到的所有小写字符z
(但请参见注释 2)[a\-z]
,[-az]
, 和[az-]
all 仅匹配 3 个字符:-
,a
, 和z
.而且,正如@pmqs 在他们的回答中指出的那样,
[z-a]
这是一个无效的范围,并且会产生错误。如果您的正则表达式包含一个带有一个或多个破折号的方括号表达式,那么您需要对其进行修改以使其按您的预期工作。与大多数事情一样,您有责任充分了解您正在使用的软件和语言功能,以便让它们按照您想要/期望的方式工作。
man perlre
有关 perl 正则表达式的详细信息,包括便利功能和您需要注意的其他“陷阱”,请参见参考资料。该手册页中有很多内容,您不会一下子掌握所有内容。在需要时回顾它,您将在未来几年中更多地了解它是如何工作的。另请参阅man perlrequick
快速参考和man perlretut
教程。以及man perlrecharclass
有关 perl 中字符类和括号表达式的更多信息。以及man perlrebackslash
有关 perl 中的反斜杠和转义序列的更多信息。(如果您的 linux 发行版或 unix 没有作为
man
页面提供的 perl 文档,则使用perldoc
as 命令来运行而不是man
,例如perldoc perlre
)。鉴于 perl 有五个主要的手册页,总计大约 54000 字的散文和专门用于正则表达式的示例(还有两个您可能永远不需要的:描述
perlreguts
perl 正则表达式引擎的工作方式和perlreapi
描述 perlre 的插件界面),您可能开始猜测这是一个复杂的话题——你是对的。笔记:
1并非所有正则表达式引擎都支持括号表达式内的转义字符。Perl 有,大多数没有——例如 GNU grep 的 BRE(默认,或
-G
)和 ERE (-E
) 没有,但 GNU grep 的 perl 兼容 (-P
) 正则表达式有。2
[[:alpha:]]
,[[:upper:]]
or[[:lower:]]
通常更适合匹配字母字符,因为它们可以处理 unicode 文本以及纯 ASCII。与字母数字字符一样[[:alnum:]]
。